mem.isa revision 4027:53292b42ee1c
15081Sgblack@eecs.umich.edu// -*- mode:c++ -*- 25081Sgblack@eecs.umich.edu 35081Sgblack@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan 47087Snate@binkert.org// All rights reserved. 57087Snate@binkert.org// 67087Snate@binkert.org// Redistribution and use in source and binary forms, with or without 77087Snate@binkert.org// modification, are permitted provided that the following conditions are 87087Snate@binkert.org// met: redistributions of source code must retain the above copyright 97087Snate@binkert.org// notice, this list of conditions and the following disclaimer; 107087Snate@binkert.org// redistributions in binary form must reproduce the above copyright 117087Snate@binkert.org// notice, this list of conditions and the following disclaimer in the 125081Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 137087Snate@binkert.org// neither the name of the copyright holders nor the names of its 147087Snate@binkert.org// contributors may be used to endorse or promote products derived from 157087Snate@binkert.org// this software without specific prior written permission. 167087Snate@binkert.org// 177087Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 187087Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 197087Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 207087Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215081Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 227087Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235081Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245081Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255081Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265081Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275081Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285081Sgblack@eecs.umich.edu// 295081Sgblack@eecs.umich.edu// Authors: Steve Reinhardt 305081Sgblack@eecs.umich.edu// Kevin Lim 315081Sgblack@eecs.umich.edu 325081Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 335081Sgblack@eecs.umich.edu// 345081Sgblack@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store 355081Sgblack@eecs.umich.edu// 365081Sgblack@eecs.umich.edu 375081Sgblack@eecs.umich.eduoutput header {{ 385081Sgblack@eecs.umich.edu /** 395081Sgblack@eecs.umich.edu * Base class for general Alpha memory-format instructions. 405081Sgblack@eecs.umich.edu */ 415081Sgblack@eecs.umich.edu class Memory : public AlphaStaticInst 425081Sgblack@eecs.umich.edu { 435081Sgblack@eecs.umich.edu protected: 445081Sgblack@eecs.umich.edu 455081Sgblack@eecs.umich.edu /// Memory request flags. See mem_req_base.hh. 465081Sgblack@eecs.umich.edu unsigned memAccessFlags; 475119Sgblack@eecs.umich.edu /// Pointer to EAComp object. 485081Sgblack@eecs.umich.edu const StaticInstPtr eaCompPtr; 495081Sgblack@eecs.umich.edu /// Pointer to MemAcc object. 505081Sgblack@eecs.umich.edu const StaticInstPtr memAccPtr; 515081Sgblack@eecs.umich.edu 525081Sgblack@eecs.umich.edu /// Constructor 535081Sgblack@eecs.umich.edu Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 545081Sgblack@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 555081Sgblack@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 565119Sgblack@eecs.umich.edu : AlphaStaticInst(mnem, _machInst, __opClass), 575081Sgblack@eecs.umich.edu memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 585081Sgblack@eecs.umich.edu { 595081Sgblack@eecs.umich.edu } 605081Sgblack@eecs.umich.edu 616082Sgblack@eecs.umich.edu std::string 626082Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 636082Sgblack@eecs.umich.edu 648610Snilay@cs.wisc.edu public: 656082Sgblack@eecs.umich.edu 666082Sgblack@eecs.umich.edu const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 676082Sgblack@eecs.umich.edu const StaticInstPtr &memAccInst() const { return memAccPtr; } 688610Snilay@cs.wisc.edu }; 696082Sgblack@eecs.umich.edu 706082Sgblack@eecs.umich.edu /** 716082Sgblack@eecs.umich.edu * Base class for memory-format instructions using a 32-bit 726082Sgblack@eecs.umich.edu * displacement (i.e. most of them). 736082Sgblack@eecs.umich.edu */ 746082Sgblack@eecs.umich.edu class MemoryDisp32 : public Memory 758610Snilay@cs.wisc.edu { 766082Sgblack@eecs.umich.edu protected: 776082Sgblack@eecs.umich.edu /// Displacement for EA calculation (signed). 786082Sgblack@eecs.umich.edu int32_t disp; 798610Snilay@cs.wisc.edu 806082Sgblack@eecs.umich.edu /// Constructor. 816082Sgblack@eecs.umich.edu MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 825081Sgblack@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 835081Sgblack@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 845119Sgblack@eecs.umich.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 855081Sgblack@eecs.umich.edu disp(MEMDISP) 865081Sgblack@eecs.umich.edu { 875081Sgblack@eecs.umich.edu } 885081Sgblack@eecs.umich.edu }; 895081Sgblack@eecs.umich.edu 905081Sgblack@eecs.umich.edu 915081Sgblack@eecs.umich.edu /** 925119Sgblack@eecs.umich.edu * Base class for a few miscellaneous memory-format insts 935081Sgblack@eecs.umich.edu * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 945081Sgblack@eecs.umich.edu * None of these instructions has a destination register either. 955081Sgblack@eecs.umich.edu */ 965081Sgblack@eecs.umich.edu class MemoryNoDisp : public Memory 976082Sgblack@eecs.umich.edu { 986082Sgblack@eecs.umich.edu protected: 998610Snilay@cs.wisc.edu /// Constructor 1006082Sgblack@eecs.umich.edu MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1016082Sgblack@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1026082Sgblack@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 1038610Snilay@cs.wisc.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1046082Sgblack@eecs.umich.edu { 1056082Sgblack@eecs.umich.edu } 1066082Sgblack@eecs.umich.edu 1076082Sgblack@eecs.umich.edu std::string 1086082Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1098610Snilay@cs.wisc.edu }; 1106082Sgblack@eecs.umich.edu}}; 1116082Sgblack@eecs.umich.edu 1126082Sgblack@eecs.umich.edu 1138610Snilay@cs.wisc.eduoutput decoder {{ 1146082Sgblack@eecs.umich.edu std::string 1156082Sgblack@eecs.umich.edu Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1165081Sgblack@eecs.umich.edu { 1175081Sgblack@eecs.umich.edu return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1185081Sgblack@eecs.umich.edu flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1195081Sgblack@eecs.umich.edu } 1205081Sgblack@eecs.umich.edu 1215081Sgblack@eecs.umich.edu std::string 1225081Sgblack@eecs.umich.edu MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1235081Sgblack@eecs.umich.edu { 1245081Sgblack@eecs.umich.edu return csprintf("%-10s (r%d)", mnemonic, RB); 1255081Sgblack@eecs.umich.edu } 1265081Sgblack@eecs.umich.edu}}; 1275081Sgblack@eecs.umich.edu 1285081Sgblack@eecs.umich.edudef format LoadAddress(code) {{ 1295081Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, 'MemoryDisp32', code) 1305081Sgblack@eecs.umich.edu header_output = BasicDeclare.subst(iop) 1315081Sgblack@eecs.umich.edu decoder_output = BasicConstructor.subst(iop) 1325081Sgblack@eecs.umich.edu decode_block = BasicDecode.subst(iop) 1335081Sgblack@eecs.umich.edu exec_output = BasicExecute.subst(iop) 1345081Sgblack@eecs.umich.edu}}; 1355081Sgblack@eecs.umich.edu 1365081Sgblack@eecs.umich.edu 1375081Sgblack@eecs.umich.edudef template LoadStoreDeclare {{ 1385081Sgblack@eecs.umich.edu /** 1395081Sgblack@eecs.umich.edu * Static instruction class for "%(mnemonic)s". 1405081Sgblack@eecs.umich.edu */ 1415081Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 1425081Sgblack@eecs.umich.edu { 1435081Sgblack@eecs.umich.edu protected: 1445081Sgblack@eecs.umich.edu 1455081Sgblack@eecs.umich.edu /** 1465081Sgblack@eecs.umich.edu * "Fake" effective address computation class for "%(mnemonic)s". 1475081Sgblack@eecs.umich.edu */ 1485081Sgblack@eecs.umich.edu class EAComp : public %(base_class)s 1495119Sgblack@eecs.umich.edu { 1505081Sgblack@eecs.umich.edu public: 1515081Sgblack@eecs.umich.edu /// Constructor 1525081Sgblack@eecs.umich.edu EAComp(ExtMachInst machInst); 1535081Sgblack@eecs.umich.edu 1545081Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1555081Sgblack@eecs.umich.edu }; 1565081Sgblack@eecs.umich.edu 1575081Sgblack@eecs.umich.edu /** 1585119Sgblack@eecs.umich.edu * "Fake" memory access instruction class for "%(mnemonic)s". 1595081Sgblack@eecs.umich.edu */ 1605081Sgblack@eecs.umich.edu class MemAcc : public %(base_class)s 1615081Sgblack@eecs.umich.edu { 1625081Sgblack@eecs.umich.edu public: 1636087Sgblack@eecs.umich.edu /// Constructor 1646087Sgblack@eecs.umich.edu MemAcc(ExtMachInst machInst); 1656087Sgblack@eecs.umich.edu 1668610Snilay@cs.wisc.edu %(BasicExecDeclare)s 1676087Sgblack@eecs.umich.edu }; 1686087Sgblack@eecs.umich.edu 1696087Sgblack@eecs.umich.edu public: 1708610Snilay@cs.wisc.edu 1716087Sgblack@eecs.umich.edu /// Constructor. 1726087Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst machInst); 1736087Sgblack@eecs.umich.edu 1746087Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1756087Sgblack@eecs.umich.edu 1766087Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1778610Snilay@cs.wisc.edu 1786087Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1796087Sgblack@eecs.umich.edu }; 1806087Sgblack@eecs.umich.edu}}; 1818610Snilay@cs.wisc.edu 1826087Sgblack@eecs.umich.edu 1836087Sgblack@eecs.umich.edudef template InitiateAccDeclare {{ 1845081Sgblack@eecs.umich.edu Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1855081Sgblack@eecs.umich.edu}}; 1865119Sgblack@eecs.umich.edu 1875081Sgblack@eecs.umich.edu 1885081Sgblack@eecs.umich.edudef template CompleteAccDeclare {{ 1895081Sgblack@eecs.umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 1905081Sgblack@eecs.umich.edu Trace::InstRecord *) const; 1915081Sgblack@eecs.umich.edu}}; 1925081Sgblack@eecs.umich.edu 1935081Sgblack@eecs.umich.edu 1945119Sgblack@eecs.umich.edudef template EACompConstructor {{ 1955081Sgblack@eecs.umich.edu /** TODO: change op_class to AddrGenOp or something (requires 1965081Sgblack@eecs.umich.edu * creating new member of OpClass enum in op_class.hh, updating 1975081Sgblack@eecs.umich.edu * config files, etc.). */ 1985081Sgblack@eecs.umich.edu inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 1996087Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2006087Sgblack@eecs.umich.edu { 2018610Snilay@cs.wisc.edu %(constructor)s; 2026087Sgblack@eecs.umich.edu } 2036087Sgblack@eecs.umich.edu}}; 2046087Sgblack@eecs.umich.edu 2058610Snilay@cs.wisc.edu 2066087Sgblack@eecs.umich.edudef template MemAccConstructor {{ 2076087Sgblack@eecs.umich.edu inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2086087Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2096087Sgblack@eecs.umich.edu { 2106087Sgblack@eecs.umich.edu %(constructor)s; 2118610Snilay@cs.wisc.edu } 2126087Sgblack@eecs.umich.edu}}; 2136087Sgblack@eecs.umich.edu 2146087Sgblack@eecs.umich.edu 2158610Snilay@cs.wisc.edudef template LoadStoreConstructor {{ 2166087Sgblack@eecs.umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2176087Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2185081Sgblack@eecs.umich.edu new EAComp(machInst), new MemAcc(machInst)) 2195081Sgblack@eecs.umich.edu { 2205081Sgblack@eecs.umich.edu %(constructor)s; 2215081Sgblack@eecs.umich.edu } 2225081Sgblack@eecs.umich.edu}}; 2235081Sgblack@eecs.umich.edu 2245081Sgblack@eecs.umich.edu 2255081Sgblack@eecs.umich.edudef template EACompExecute {{ 2265081Sgblack@eecs.umich.edu Fault 2275081Sgblack@eecs.umich.edu %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2285081Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2295081Sgblack@eecs.umich.edu { 2305081Sgblack@eecs.umich.edu Addr EA; 2315081Sgblack@eecs.umich.edu Fault fault = NoFault; 2325081Sgblack@eecs.umich.edu 2335081Sgblack@eecs.umich.edu %(fp_enable_check)s; 2345081Sgblack@eecs.umich.edu %(op_decl)s; 2355081Sgblack@eecs.umich.edu %(op_rd)s; 2365081Sgblack@eecs.umich.edu %(ea_code)s; 2375081Sgblack@eecs.umich.edu 2385081Sgblack@eecs.umich.edu if (fault == NoFault) { 2395081Sgblack@eecs.umich.edu %(op_wb)s; 2405081Sgblack@eecs.umich.edu xc->setEA(EA); 2415081Sgblack@eecs.umich.edu } 2425081Sgblack@eecs.umich.edu 2435081Sgblack@eecs.umich.edu return fault; 2445081Sgblack@eecs.umich.edu } 2455081Sgblack@eecs.umich.edu}}; 2465081Sgblack@eecs.umich.edu 2475081Sgblack@eecs.umich.edudef template LoadMemAccExecute {{ 2485081Sgblack@eecs.umich.edu Fault 2495081Sgblack@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2505081Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2515081Sgblack@eecs.umich.edu { 2525081Sgblack@eecs.umich.edu Addr EA; 2535081Sgblack@eecs.umich.edu Fault fault = NoFault; 2545081Sgblack@eecs.umich.edu 2555081Sgblack@eecs.umich.edu %(fp_enable_check)s; 2565081Sgblack@eecs.umich.edu %(op_decl)s; 2575119Sgblack@eecs.umich.edu %(op_rd)s; 2585081Sgblack@eecs.umich.edu EA = xc->getEA(); 2595081Sgblack@eecs.umich.edu 2605081Sgblack@eecs.umich.edu if (fault == NoFault) { 2615081Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2625081Sgblack@eecs.umich.edu %(memacc_code)s; 2635081Sgblack@eecs.umich.edu } 2645081Sgblack@eecs.umich.edu 2655081Sgblack@eecs.umich.edu if (fault == NoFault) { 2665119Sgblack@eecs.umich.edu %(op_wb)s; 2675081Sgblack@eecs.umich.edu } 2685081Sgblack@eecs.umich.edu 2695081Sgblack@eecs.umich.edu return fault; 2705081Sgblack@eecs.umich.edu } 2715081Sgblack@eecs.umich.edu}}; 2726085Sgblack@eecs.umich.edu 2736085Sgblack@eecs.umich.edu 2748610Snilay@cs.wisc.edudef template LoadExecute {{ 2756085Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2766085Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2776085Sgblack@eecs.umich.edu { 2786085Sgblack@eecs.umich.edu Addr EA; 2798610Snilay@cs.wisc.edu Fault fault = NoFault; 2806085Sgblack@eecs.umich.edu 2816085Sgblack@eecs.umich.edu %(fp_enable_check)s; 2826085Sgblack@eecs.umich.edu %(op_decl)s; 2836085Sgblack@eecs.umich.edu %(op_rd)s; 2846085Sgblack@eecs.umich.edu %(ea_code)s; 2858610Snilay@cs.wisc.edu 2866085Sgblack@eecs.umich.edu if (fault == NoFault) { 2876085Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2886085Sgblack@eecs.umich.edu %(memacc_code)s; 2896085Sgblack@eecs.umich.edu } 2908610Snilay@cs.wisc.edu 2916085Sgblack@eecs.umich.edu if (fault == NoFault) { 2926085Sgblack@eecs.umich.edu %(op_wb)s; 2935081Sgblack@eecs.umich.edu } 2945081Sgblack@eecs.umich.edu 2955119Sgblack@eecs.umich.edu return fault; 2965081Sgblack@eecs.umich.edu } 2975081Sgblack@eecs.umich.edu}}; 2985081Sgblack@eecs.umich.edu 2995081Sgblack@eecs.umich.edu 3005081Sgblack@eecs.umich.edudef template LoadInitiateAcc {{ 3015081Sgblack@eecs.umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3025081Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 3035119Sgblack@eecs.umich.edu { 3045081Sgblack@eecs.umich.edu Addr EA; 3055081Sgblack@eecs.umich.edu Fault fault = NoFault; 3065081Sgblack@eecs.umich.edu 3075081Sgblack@eecs.umich.edu %(fp_enable_check)s; 3086085Sgblack@eecs.umich.edu %(op_src_decl)s; 3096085Sgblack@eecs.umich.edu %(op_rd)s; 3108610Snilay@cs.wisc.edu %(ea_code)s; 3116085Sgblack@eecs.umich.edu 3126085Sgblack@eecs.umich.edu if (fault == NoFault) { 3136085Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3148610Snilay@cs.wisc.edu } 3156085Sgblack@eecs.umich.edu 3166085Sgblack@eecs.umich.edu return fault; 3176085Sgblack@eecs.umich.edu } 3186085Sgblack@eecs.umich.edu}}; 3196085Sgblack@eecs.umich.edu 3208610Snilay@cs.wisc.edu 3216085Sgblack@eecs.umich.edudef template LoadCompleteAcc {{ 3226085Sgblack@eecs.umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 3236085Sgblack@eecs.umich.edu %(CPU_exec_context)s *xc, 3248610Snilay@cs.wisc.edu Trace::InstRecord *traceData) const 3256085Sgblack@eecs.umich.edu { 3266085Sgblack@eecs.umich.edu Fault fault = NoFault; 3275081Sgblack@eecs.umich.edu 3285081Sgblack@eecs.umich.edu %(fp_enable_check)s; 3295081Sgblack@eecs.umich.edu %(op_decl)s; 3305081Sgblack@eecs.umich.edu 3315081Sgblack@eecs.umich.edu Mem = pkt->get<typeof(Mem)>(); 3325081Sgblack@eecs.umich.edu 3335081Sgblack@eecs.umich.edu if (fault == NoFault) { 3345081Sgblack@eecs.umich.edu %(memacc_code)s; 3355081Sgblack@eecs.umich.edu } 3365119Sgblack@eecs.umich.edu 3375081Sgblack@eecs.umich.edu if (fault == NoFault) { 3385081Sgblack@eecs.umich.edu %(op_wb)s; 3395081Sgblack@eecs.umich.edu } 3405081Sgblack@eecs.umich.edu 3415081Sgblack@eecs.umich.edu return fault; 3425081Sgblack@eecs.umich.edu } 3435081Sgblack@eecs.umich.edu}}; 3445081Sgblack@eecs.umich.edu 3455119Sgblack@eecs.umich.edu 3465081Sgblack@eecs.umich.edudef template StoreMemAccExecute {{ 3475081Sgblack@eecs.umich.edu Fault 3485081Sgblack@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3496089Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 3506089Sgblack@eecs.umich.edu { 3516089Sgblack@eecs.umich.edu Addr EA; 3526089Sgblack@eecs.umich.edu Fault fault = NoFault; 3538610Snilay@cs.wisc.edu 3546089Sgblack@eecs.umich.edu %(fp_enable_check)s; 3556089Sgblack@eecs.umich.edu %(op_decl)s; 3566089Sgblack@eecs.umich.edu %(op_rd)s; 3578610Snilay@cs.wisc.edu EA = xc->getEA(); 3586089Sgblack@eecs.umich.edu 3596089Sgblack@eecs.umich.edu if (fault == NoFault) { 3606089Sgblack@eecs.umich.edu %(memacc_code)s; 3616089Sgblack@eecs.umich.edu } 3626089Sgblack@eecs.umich.edu 3636089Sgblack@eecs.umich.edu if (fault == NoFault) { 3648610Snilay@cs.wisc.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3656089Sgblack@eecs.umich.edu memAccessFlags, NULL); 3666089Sgblack@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 3676089Sgblack@eecs.umich.edu } 3688610Snilay@cs.wisc.edu 3696089Sgblack@eecs.umich.edu if (fault == NoFault) { 3705081Sgblack@eecs.umich.edu %(postacc_code)s; 371 } 372 373 if (fault == NoFault) { 374 %(op_wb)s; 375 } 376 377 return fault; 378 } 379}}; 380 381def template StoreCondMemAccExecute {{ 382 Fault 383 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 384 Trace::InstRecord *traceData) const 385 { 386 Addr EA; 387 Fault fault = NoFault; 388 uint64_t write_result = 0; 389 390 %(fp_enable_check)s; 391 %(op_decl)s; 392 %(op_rd)s; 393 EA = xc->getEA(); 394 395 if (fault == NoFault) { 396 %(memacc_code)s; 397 } 398 399 if (fault == NoFault) { 400 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 401 memAccessFlags, &write_result); 402 if (traceData) { traceData->setData(Mem); } 403 } 404 405 if (fault == NoFault) { 406 %(postacc_code)s; 407 } 408 409 if (fault == NoFault) { 410 %(op_wb)s; 411 } 412 413 return fault; 414 } 415}}; 416 417 418def template StoreExecute {{ 419 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 420 Trace::InstRecord *traceData) const 421 { 422 Addr EA; 423 Fault fault = NoFault; 424 425 %(fp_enable_check)s; 426 %(op_decl)s; 427 %(op_rd)s; 428 %(ea_code)s; 429 430 if (fault == NoFault) { 431 %(memacc_code)s; 432 } 433 434 if (fault == NoFault) { 435 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 436 memAccessFlags, NULL); 437 if (traceData) { traceData->setData(Mem); } 438 } 439 440 if (fault == NoFault) { 441 %(postacc_code)s; 442 } 443 444 if (fault == NoFault) { 445 %(op_wb)s; 446 } 447 448 return fault; 449 } 450}}; 451 452def template StoreCondExecute {{ 453 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 454 Trace::InstRecord *traceData) const 455 { 456 Addr EA; 457 Fault fault = NoFault; 458 uint64_t write_result = 0; 459 460 %(fp_enable_check)s; 461 %(op_decl)s; 462 %(op_rd)s; 463 %(ea_code)s; 464 465 if (fault == NoFault) { 466 %(memacc_code)s; 467 } 468 469 if (fault == NoFault) { 470 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 471 memAccessFlags, &write_result); 472 if (traceData) { traceData->setData(Mem); } 473 } 474 475 if (fault == NoFault) { 476 %(postacc_code)s; 477 } 478 479 if (fault == NoFault) { 480 %(op_wb)s; 481 } 482 483 return fault; 484 } 485}}; 486 487def template StoreInitiateAcc {{ 488 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 489 Trace::InstRecord *traceData) const 490 { 491 Addr EA; 492 Fault fault = NoFault; 493 494 %(fp_enable_check)s; 495 %(op_decl)s; 496 %(op_rd)s; 497 %(ea_code)s; 498 499 if (fault == NoFault) { 500 %(memacc_code)s; 501 } 502 503 if (fault == NoFault) { 504 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 505 memAccessFlags, NULL); 506 if (traceData) { traceData->setData(Mem); } 507 } 508 509 return fault; 510 } 511}}; 512 513 514def template StoreCompleteAcc {{ 515 Fault %(class_name)s::completeAcc(PacketPtr pkt, 516 %(CPU_exec_context)s *xc, 517 Trace::InstRecord *traceData) const 518 { 519 Fault fault = NoFault; 520 521 %(fp_enable_check)s; 522 %(op_dest_decl)s; 523 524 if (fault == NoFault) { 525 %(postacc_code)s; 526 } 527 528 if (fault == NoFault) { 529 %(op_wb)s; 530 } 531 532 return fault; 533 } 534}}; 535 536 537def template StoreCondCompleteAcc {{ 538 Fault %(class_name)s::completeAcc(PacketPtr pkt, 539 %(CPU_exec_context)s *xc, 540 Trace::InstRecord *traceData) const 541 { 542 Fault fault = NoFault; 543 544 %(fp_enable_check)s; 545 %(op_dest_decl)s; 546 547 uint64_t write_result = pkt->req->getScResult(); 548 549 if (fault == NoFault) { 550 %(postacc_code)s; 551 } 552 553 if (fault == NoFault) { 554 %(op_wb)s; 555 } 556 557 return fault; 558 } 559}}; 560 561 562def template MiscMemAccExecute {{ 563 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 564 Trace::InstRecord *traceData) const 565 { 566 Addr EA; 567 Fault fault = NoFault; 568 569 %(fp_enable_check)s; 570 %(op_decl)s; 571 %(op_rd)s; 572 EA = xc->getEA(); 573 574 if (fault == NoFault) { 575 %(memacc_code)s; 576 } 577 578 return NoFault; 579 } 580}}; 581 582def template MiscExecute {{ 583 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 584 Trace::InstRecord *traceData) const 585 { 586 Addr EA; 587 Fault fault = NoFault; 588 589 %(fp_enable_check)s; 590 %(op_decl)s; 591 %(op_rd)s; 592 %(ea_code)s; 593 594 if (fault == NoFault) { 595 %(memacc_code)s; 596 } 597 598 return NoFault; 599 } 600}}; 601 602def template MiscInitiateAcc {{ 603 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 604 Trace::InstRecord *traceData) const 605 { 606 warn("Misc instruction does not support split access method!"); 607 return NoFault; 608 } 609}}; 610 611 612def template MiscCompleteAcc {{ 613 Fault %(class_name)s::completeAcc(PacketPtr pkt, 614 %(CPU_exec_context)s *xc, 615 Trace::InstRecord *traceData) const 616 { 617 warn("Misc instruction does not support split access method!"); 618 619 return NoFault; 620 } 621}}; 622 623// load instructions use Ra as dest, so check for 624// Ra == 31 to detect nops 625def template LoadNopCheckDecode {{ 626 { 627 AlphaStaticInst *i = new %(class_name)s(machInst); 628 if (RA == 31) { 629 i = makeNop(i); 630 } 631 return i; 632 } 633}}; 634 635 636// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 637def template LoadPrefetchCheckDecode {{ 638 { 639 if (RA != 31) { 640 return new %(class_name)s(machInst); 641 } 642 else { 643 return new %(class_name)sPrefetch(machInst); 644 } 645 } 646}}; 647 648 649let {{ 650def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 651 postacc_code = '', base_class = 'MemoryDisp32', 652 decode_template = BasicDecode, exec_template_base = ''): 653 # Make sure flags are in lists (convert to lists if not). 654 mem_flags = makeList(mem_flags) 655 inst_flags = makeList(inst_flags) 656 657 # add hook to get effective addresses into execution trace output. 658 ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 659 660 # Some CPU models execute the memory operation as an atomic unit, 661 # while others want to separate them into an effective address 662 # computation and a memory access operation. As a result, we need 663 # to generate three StaticInst objects. Note that the latter two 664 # are nested inside the larger "atomic" one. 665 666 # Generate InstObjParams for each of the three objects. Note that 667 # they differ only in the set of code objects contained (which in 668 # turn affects the object's overall operand list). 669 iop = InstObjParams(name, Name, base_class, 670 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 671 inst_flags) 672 ea_iop = InstObjParams(name, Name, base_class, 673 { 'ea_code':ea_code }, 674 inst_flags) 675 memacc_iop = InstObjParams(name, Name, base_class, 676 { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 677 inst_flags) 678 679 if mem_flags: 680 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 681 iop.constructor += s 682 memacc_iop.constructor += s 683 684 # select templates 685 686 # The InitiateAcc template is the same for StoreCond templates as the 687 # corresponding Store template.. 688 StoreCondInitiateAcc = StoreInitiateAcc 689 690 memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 691 fullExecTemplate = eval(exec_template_base + 'Execute') 692 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 693 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 694 695 # (header_output, decoder_output, decode_block, exec_output) 696 return (LoadStoreDeclare.subst(iop), 697 EACompConstructor.subst(ea_iop) 698 + MemAccConstructor.subst(memacc_iop) 699 + LoadStoreConstructor.subst(iop), 700 decode_template.subst(iop), 701 EACompExecute.subst(ea_iop) 702 + memAccExecTemplate.subst(memacc_iop) 703 + fullExecTemplate.subst(iop) 704 + initiateAccTemplate.subst(iop) 705 + completeAccTemplate.subst(iop)) 706}}; 707 708def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 709 mem_flags = [], inst_flags = []) {{ 710 (header_output, decoder_output, decode_block, exec_output) = \ 711 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 712 decode_template = LoadNopCheckDecode, 713 exec_template_base = 'Load') 714}}; 715 716 717// Note that the flags passed in apply only to the prefetch version 718def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 719 mem_flags = [], pf_flags = [], inst_flags = []) {{ 720 # declare the load instruction object and generate the decode block 721 (header_output, decoder_output, decode_block, exec_output) = \ 722 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 723 decode_template = LoadPrefetchCheckDecode, 724 exec_template_base = 'Load') 725 726 # Declare the prefetch instruction object. 727 728 # Make sure flag args are lists so we can mess with them. 729 mem_flags = makeList(mem_flags) 730 pf_flags = makeList(pf_flags) 731 inst_flags = makeList(inst_flags) 732 733 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 734 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 735 'IsDataPrefetch', 'MemReadOp'] 736 737 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 738 LoadStoreBase(name, Name + 'Prefetch', ea_code, 739 'xc->prefetch(EA, memAccessFlags);', 740 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 741 742 header_output += pf_header_output 743 decoder_output += pf_decoder_output 744 exec_output += pf_exec_output 745}}; 746 747 748def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 749 mem_flags = [], inst_flags = []) {{ 750 (header_output, decoder_output, decode_block, exec_output) = \ 751 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 752 exec_template_base = 'Store') 753}}; 754 755 756def format StoreCond(memacc_code, postacc_code, 757 ea_code = {{ EA = Rb + disp; }}, 758 mem_flags = [], inst_flags = []) {{ 759 (header_output, decoder_output, decode_block, exec_output) = \ 760 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 761 postacc_code, exec_template_base = 'StoreCond') 762}}; 763 764 765// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 766def format MiscPrefetch(ea_code, memacc_code, 767 mem_flags = [], inst_flags = []) {{ 768 (header_output, decoder_output, decode_block, exec_output) = \ 769 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 770 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 771}}; 772 773 774