mem.isa revision 4661
17118Sgblack@eecs.umich.edu// -*- mode:c++ -*- 27118Sgblack@eecs.umich.edu 37118Sgblack@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan 47118Sgblack@eecs.umich.edu// All rights reserved. 57118Sgblack@eecs.umich.edu// 67118Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 77118Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 87118Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 97118Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 107118Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 117118Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 127118Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 137118Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 147118Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 156253Sgblack@eecs.umich.edu// this software without specific prior written permission. 166253Sgblack@eecs.umich.edu// 176253Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186253Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196253Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206253Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216253Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226253Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236253Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246253Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256253Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266253Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276253Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286253Sgblack@eecs.umich.edu// 296253Sgblack@eecs.umich.edu// Authors: Steve Reinhardt 306253Sgblack@eecs.umich.edu// Kevin Lim 316253Sgblack@eecs.umich.edu 326253Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 336253Sgblack@eecs.umich.edu// 346253Sgblack@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store 356253Sgblack@eecs.umich.edu// 366253Sgblack@eecs.umich.edu 376253Sgblack@eecs.umich.eduoutput header {{ 386253Sgblack@eecs.umich.edu /** 396253Sgblack@eecs.umich.edu * Base class for general Alpha memory-format instructions. 406253Sgblack@eecs.umich.edu */ 416253Sgblack@eecs.umich.edu class Memory : public AlphaStaticInst 426253Sgblack@eecs.umich.edu { 436253Sgblack@eecs.umich.edu protected: 446253Sgblack@eecs.umich.edu 456253Sgblack@eecs.umich.edu /// Memory request flags. See mem_req_base.hh. 466253Sgblack@eecs.umich.edu unsigned memAccessFlags; 476253Sgblack@eecs.umich.edu /// Pointer to EAComp object. 486253Sgblack@eecs.umich.edu const StaticInstPtr eaCompPtr; 497118Sgblack@eecs.umich.edu /// Pointer to MemAcc object. 507205Sgblack@eecs.umich.edu const StaticInstPtr memAccPtr; 517205Sgblack@eecs.umich.edu 527205Sgblack@eecs.umich.edu /// Constructor 537205Sgblack@eecs.umich.edu Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 547205Sgblack@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 557205Sgblack@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 567205Sgblack@eecs.umich.edu : AlphaStaticInst(mnem, _machInst, __opClass), 577205Sgblack@eecs.umich.edu memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 587205Sgblack@eecs.umich.edu { 597205Sgblack@eecs.umich.edu } 607205Sgblack@eecs.umich.edu 617205Sgblack@eecs.umich.edu std::string 627205Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 6312616Sgabeblack@google.com 6412616Sgabeblack@google.com public: 657205Sgblack@eecs.umich.edu 667205Sgblack@eecs.umich.edu const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 677720Sgblack@eecs.umich.edu const StaticInstPtr &memAccInst() const { return memAccPtr; } 687720Sgblack@eecs.umich.edu }; 697720Sgblack@eecs.umich.edu 707720Sgblack@eecs.umich.edu /** 717720Sgblack@eecs.umich.edu * Base class for memory-format instructions using a 32-bit 727720Sgblack@eecs.umich.edu * displacement (i.e. most of them). 737720Sgblack@eecs.umich.edu */ 747720Sgblack@eecs.umich.edu class MemoryDisp32 : public Memory 757720Sgblack@eecs.umich.edu { 767720Sgblack@eecs.umich.edu protected: 777720Sgblack@eecs.umich.edu /// Displacement for EA calculation (signed). 787720Sgblack@eecs.umich.edu int32_t disp; 797720Sgblack@eecs.umich.edu 807720Sgblack@eecs.umich.edu /// Constructor. 817720Sgblack@eecs.umich.edu MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 827720Sgblack@eecs.umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 837720Sgblack@eecs.umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 847720Sgblack@eecs.umich.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 857720Sgblack@eecs.umich.edu disp(MEMDISP) 867720Sgblack@eecs.umich.edu { 877291Sgblack@eecs.umich.edu } 887720Sgblack@eecs.umich.edu }; 897291Sgblack@eecs.umich.edu 907291Sgblack@eecs.umich.edu 917291Sgblack@eecs.umich.edu /** 927291Sgblack@eecs.umich.edu * Base class for a few miscellaneous memory-format insts 937291Sgblack@eecs.umich.edu * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 947291Sgblack@eecs.umich.edu * None of these instructions has a destination register either. 957291Sgblack@eecs.umich.edu */ 967291Sgblack@eecs.umich.edu class MemoryNoDisp : public Memory 977291Sgblack@eecs.umich.edu { 987291Sgblack@eecs.umich.edu protected: 997291Sgblack@eecs.umich.edu /// Constructor 1007291Sgblack@eecs.umich.edu MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1018140SMatt.Horsnell@arm.com StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1028140SMatt.Horsnell@arm.com StaticInstPtr _memAccPtr = nullStaticInstPtr) 1037646Sgene.wu@arm.com : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1047646Sgene.wu@arm.com { 1057291Sgblack@eecs.umich.edu } 1067291Sgblack@eecs.umich.edu 1077291Sgblack@eecs.umich.edu std::string 1087720Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1098140SMatt.Horsnell@arm.com }; 1108140SMatt.Horsnell@arm.com}}; 1118140SMatt.Horsnell@arm.com 1128140SMatt.Horsnell@arm.com 1137291Sgblack@eecs.umich.eduoutput decoder {{ 1147291Sgblack@eecs.umich.edu std::string 1157646Sgene.wu@arm.com Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1167646Sgene.wu@arm.com { 1177646Sgene.wu@arm.com return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1187747SAli.Saidi@ARM.com flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1197646Sgene.wu@arm.com } 1207646Sgene.wu@arm.com 1217646Sgene.wu@arm.com std::string 12212616Sgabeblack@google.com MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1237646Sgene.wu@arm.com { 1247646Sgene.wu@arm.com return csprintf("%-10s (r%d)", mnemonic, RB); 1257646Sgene.wu@arm.com } 1267646Sgene.wu@arm.com}}; 1277646Sgene.wu@arm.com 12812616Sgabeblack@google.comdef format LoadAddress(code) {{ 12912616Sgabeblack@google.com iop = InstObjParams(name, Name, 'MemoryDisp32', code) 1307291Sgblack@eecs.umich.edu header_output = BasicDeclare.subst(iop) 1317291Sgblack@eecs.umich.edu decoder_output = BasicConstructor.subst(iop) 1327312Sgblack@eecs.umich.edu decode_block = BasicDecode.subst(iop) 1337720Sgblack@eecs.umich.edu exec_output = BasicExecute.subst(iop) 1347312Sgblack@eecs.umich.edu}}; 1357312Sgblack@eecs.umich.edu 1367312Sgblack@eecs.umich.edu 1377312Sgblack@eecs.umich.edudef template LoadStoreDeclare {{ 1387312Sgblack@eecs.umich.edu /** 1397312Sgblack@eecs.umich.edu * Static instruction class for "%(mnemonic)s". 1407312Sgblack@eecs.umich.edu */ 1417312Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 1427312Sgblack@eecs.umich.edu { 1437312Sgblack@eecs.umich.edu protected: 1447312Sgblack@eecs.umich.edu 1457312Sgblack@eecs.umich.edu /** 1467646Sgene.wu@arm.com * "Fake" effective address computation class for "%(mnemonic)s". 1477646Sgene.wu@arm.com */ 1487646Sgene.wu@arm.com class EAComp : public %(base_class)s 1497312Sgblack@eecs.umich.edu { 1507312Sgblack@eecs.umich.edu public: 1517312Sgblack@eecs.umich.edu /// Constructor 1527720Sgblack@eecs.umich.edu EAComp(ExtMachInst machInst); 1537646Sgene.wu@arm.com 1547312Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1557312Sgblack@eecs.umich.edu }; 1567646Sgene.wu@arm.com 1577646Sgene.wu@arm.com /** 1587646Sgene.wu@arm.com * "Fake" memory access instruction class for "%(mnemonic)s". 1597845SAli.Saidi@ARM.com */ 1607646Sgene.wu@arm.com class MemAcc : public %(base_class)s 1617646Sgene.wu@arm.com { 1627646Sgene.wu@arm.com public: 16312616Sgabeblack@google.com /// Constructor 1647646Sgene.wu@arm.com MemAcc(ExtMachInst machInst); 1657646Sgene.wu@arm.com 1667646Sgene.wu@arm.com %(BasicExecDeclare)s 1677646Sgene.wu@arm.com }; 1687646Sgene.wu@arm.com 16912616Sgabeblack@google.com public: 17012616Sgabeblack@google.com 1717312Sgblack@eecs.umich.edu /// Constructor. 1727312Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst machInst); 1737720Sgblack@eecs.umich.edu 1747118Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1757118Sgblack@eecs.umich.edu 1767118Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1777118Sgblack@eecs.umich.edu 1787118Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1797118Sgblack@eecs.umich.edu }; 1807118Sgblack@eecs.umich.edu}}; 1817118Sgblack@eecs.umich.edu 1827118Sgblack@eecs.umich.edu 1837118Sgblack@eecs.umich.edudef template InitiateAccDeclare {{ 1847118Sgblack@eecs.umich.edu Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1857118Sgblack@eecs.umich.edu}}; 1867118Sgblack@eecs.umich.edu 1877646Sgene.wu@arm.com 1887646Sgene.wu@arm.comdef template CompleteAccDeclare {{ 1897646Sgene.wu@arm.com Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 1907118Sgblack@eecs.umich.edu Trace::InstRecord *) const; 1917132Sgblack@eecs.umich.edu}}; 1927132Sgblack@eecs.umich.edu 1937720Sgblack@eecs.umich.edu 1947646Sgene.wu@arm.comdef template EACompConstructor {{ 1957118Sgblack@eecs.umich.edu /** TODO: change op_class to AddrGenOp or something (requires 1967118Sgblack@eecs.umich.edu * creating new member of OpClass enum in op_class.hh, updating 1977646Sgene.wu@arm.com * config files, etc.). */ 1987646Sgene.wu@arm.com inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 1997646Sgene.wu@arm.com : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2007646Sgene.wu@arm.com { 2017646Sgene.wu@arm.com %(constructor)s; 2027646Sgene.wu@arm.com } 2037646Sgene.wu@arm.com}}; 20412616Sgabeblack@google.com 2057646Sgene.wu@arm.com 2067646Sgene.wu@arm.comdef template MemAccConstructor {{ 2077646Sgene.wu@arm.com inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2087646Sgene.wu@arm.com : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2097646Sgene.wu@arm.com { 2107118Sgblack@eecs.umich.edu %(constructor)s; 2117118Sgblack@eecs.umich.edu } 2127118Sgblack@eecs.umich.edu}}; 2137118Sgblack@eecs.umich.edu 2147279Sgblack@eecs.umich.edu 2157279Sgblack@eecs.umich.edudef template LoadStoreConstructor {{ 2167279Sgblack@eecs.umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 21712104Snathanael.premillieu@arm.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2187279Sgblack@eecs.umich.edu new EAComp(machInst), new MemAcc(machInst)) 2197279Sgblack@eecs.umich.edu { 2207118Sgblack@eecs.umich.edu %(constructor)s; 2217118Sgblack@eecs.umich.edu } 2227118Sgblack@eecs.umich.edu}}; 2237118Sgblack@eecs.umich.edu 2247132Sgblack@eecs.umich.edu 2257118Sgblack@eecs.umich.edudef template EACompExecute {{ 2267118Sgblack@eecs.umich.edu Fault 2277118Sgblack@eecs.umich.edu %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2287118Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2297132Sgblack@eecs.umich.edu { 2307132Sgblack@eecs.umich.edu Addr EA; 2317132Sgblack@eecs.umich.edu Fault fault = NoFault; 2327118Sgblack@eecs.umich.edu 2337118Sgblack@eecs.umich.edu %(fp_enable_check)s; 2347118Sgblack@eecs.umich.edu %(op_decl)s; 2357118Sgblack@eecs.umich.edu %(op_rd)s; 2367118Sgblack@eecs.umich.edu %(ea_code)s; 2377118Sgblack@eecs.umich.edu 2387118Sgblack@eecs.umich.edu if (fault == NoFault) { 2397118Sgblack@eecs.umich.edu %(op_wb)s; 2407118Sgblack@eecs.umich.edu xc->setEA(EA); 2417118Sgblack@eecs.umich.edu } 2427118Sgblack@eecs.umich.edu 2437118Sgblack@eecs.umich.edu return fault; 2447303Sgblack@eecs.umich.edu } 2457303Sgblack@eecs.umich.edu}}; 2467303Sgblack@eecs.umich.edu 2477303Sgblack@eecs.umich.edudef template LoadMemAccExecute {{ 2487303Sgblack@eecs.umich.edu Fault 2497303Sgblack@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2507303Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2517303Sgblack@eecs.umich.edu { 2527303Sgblack@eecs.umich.edu Addr EA; 2537303Sgblack@eecs.umich.edu Fault fault = NoFault; 2547303Sgblack@eecs.umich.edu 2557303Sgblack@eecs.umich.edu %(fp_enable_check)s; 2567303Sgblack@eecs.umich.edu %(op_decl)s; 2577303Sgblack@eecs.umich.edu %(op_rd)s; 2587303Sgblack@eecs.umich.edu EA = xc->getEA(); 25912104Snathanael.premillieu@arm.com 2607303Sgblack@eecs.umich.edu if (fault == NoFault) { 2617303Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2627303Sgblack@eecs.umich.edu %(memacc_code)s; 2637303Sgblack@eecs.umich.edu } 2647303Sgblack@eecs.umich.edu 2657279Sgblack@eecs.umich.edu if (fault == NoFault) { 2667279Sgblack@eecs.umich.edu %(op_wb)s; 2677279Sgblack@eecs.umich.edu } 2687279Sgblack@eecs.umich.edu 2697279Sgblack@eecs.umich.edu return fault; 2707279Sgblack@eecs.umich.edu } 2717279Sgblack@eecs.umich.edu}}; 2727279Sgblack@eecs.umich.edu 2737279Sgblack@eecs.umich.edu 2747279Sgblack@eecs.umich.edudef template LoadExecute {{ 2757279Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2767279Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2777279Sgblack@eecs.umich.edu { 2787279Sgblack@eecs.umich.edu Addr EA; 2797279Sgblack@eecs.umich.edu Fault fault = NoFault; 2807279Sgblack@eecs.umich.edu 2817279Sgblack@eecs.umich.edu %(fp_enable_check)s; 2827279Sgblack@eecs.umich.edu %(op_decl)s; 28312104Snathanael.premillieu@arm.com %(op_rd)s; 2847279Sgblack@eecs.umich.edu %(ea_code)s; 2857279Sgblack@eecs.umich.edu 2867279Sgblack@eecs.umich.edu if (fault == NoFault) { 2877303Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2887303Sgblack@eecs.umich.edu %(memacc_code)s; 2897303Sgblack@eecs.umich.edu } 2907303Sgblack@eecs.umich.edu 2917303Sgblack@eecs.umich.edu if (fault == NoFault) { 2927303Sgblack@eecs.umich.edu %(op_wb)s; 2937303Sgblack@eecs.umich.edu } 2947303Sgblack@eecs.umich.edu 2957303Sgblack@eecs.umich.edu return fault; 2967303Sgblack@eecs.umich.edu } 2977303Sgblack@eecs.umich.edu}}; 2987303Sgblack@eecs.umich.edu 2997303Sgblack@eecs.umich.edu 3007303Sgblack@eecs.umich.edudef template LoadInitiateAcc {{ 3017303Sgblack@eecs.umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 30212104Snathanael.premillieu@arm.com Trace::InstRecord *traceData) const 3037303Sgblack@eecs.umich.edu { 3047303Sgblack@eecs.umich.edu Addr EA; 3057303Sgblack@eecs.umich.edu Fault fault = NoFault; 3067303Sgblack@eecs.umich.edu 3077303Sgblack@eecs.umich.edu %(fp_enable_check)s; 3087118Sgblack@eecs.umich.edu %(op_src_decl)s; 3097132Sgblack@eecs.umich.edu %(op_rd)s; 3107118Sgblack@eecs.umich.edu %(ea_code)s; 3117118Sgblack@eecs.umich.edu 3127118Sgblack@eecs.umich.edu if (fault == NoFault) { 3137118Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3147118Sgblack@eecs.umich.edu } 3157118Sgblack@eecs.umich.edu 3167132Sgblack@eecs.umich.edu return fault; 3177132Sgblack@eecs.umich.edu } 3187132Sgblack@eecs.umich.edu}}; 3197132Sgblack@eecs.umich.edu 3207132Sgblack@eecs.umich.edu 3217118Sgblack@eecs.umich.edudef template LoadCompleteAcc {{ 3227118Sgblack@eecs.umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 3237118Sgblack@eecs.umich.edu %(CPU_exec_context)s *xc, 3247428Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 3257118Sgblack@eecs.umich.edu { 3267118Sgblack@eecs.umich.edu Fault fault = NoFault; 3277279Sgblack@eecs.umich.edu 3287279Sgblack@eecs.umich.edu %(fp_enable_check)s; 3297279Sgblack@eecs.umich.edu %(op_decl)s; 3307279Sgblack@eecs.umich.edu 3317279Sgblack@eecs.umich.edu Mem = pkt->get<typeof(Mem)>(); 3327279Sgblack@eecs.umich.edu 3337279Sgblack@eecs.umich.edu if (fault == NoFault) { 3347279Sgblack@eecs.umich.edu %(memacc_code)s; 3357279Sgblack@eecs.umich.edu } 3367279Sgblack@eecs.umich.edu 3377279Sgblack@eecs.umich.edu if (fault == NoFault) { 3387279Sgblack@eecs.umich.edu %(op_wb)s; 3397279Sgblack@eecs.umich.edu } 3407279Sgblack@eecs.umich.edu 3417279Sgblack@eecs.umich.edu return fault; 3427279Sgblack@eecs.umich.edu } 3437279Sgblack@eecs.umich.edu}}; 3447279Sgblack@eecs.umich.edu 3457279Sgblack@eecs.umich.edu 3467279Sgblack@eecs.umich.edudef template StoreMemAccExecute {{ 34712104Snathanael.premillieu@arm.com Fault 3487279Sgblack@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3497279Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 3507279Sgblack@eecs.umich.edu { 3517118Sgblack@eecs.umich.edu Addr EA; 3527132Sgblack@eecs.umich.edu Fault fault = NoFault; 3537118Sgblack@eecs.umich.edu 3547118Sgblack@eecs.umich.edu %(fp_enable_check)s; 3557132Sgblack@eecs.umich.edu %(op_decl)s; 3567132Sgblack@eecs.umich.edu %(op_rd)s; 3577132Sgblack@eecs.umich.edu EA = xc->getEA(); 3587132Sgblack@eecs.umich.edu 3597132Sgblack@eecs.umich.edu if (fault == NoFault) { 3607132Sgblack@eecs.umich.edu %(memacc_code)s; 3617132Sgblack@eecs.umich.edu } 3627132Sgblack@eecs.umich.edu 3637132Sgblack@eecs.umich.edu if (fault == NoFault) { 3647132Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3657132Sgblack@eecs.umich.edu memAccessFlags, NULL); 3667132Sgblack@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 3677132Sgblack@eecs.umich.edu } 3687132Sgblack@eecs.umich.edu 3697279Sgblack@eecs.umich.edu if (fault == NoFault) { 3707279Sgblack@eecs.umich.edu %(postacc_code)s; 3717279Sgblack@eecs.umich.edu } 3727279Sgblack@eecs.umich.edu 3737279Sgblack@eecs.umich.edu if (fault == NoFault) { 3747279Sgblack@eecs.umich.edu %(op_wb)s; 3757279Sgblack@eecs.umich.edu } 3767303Sgblack@eecs.umich.edu 3777303Sgblack@eecs.umich.edu return fault; 3787303Sgblack@eecs.umich.edu } 3797303Sgblack@eecs.umich.edu}}; 3807303Sgblack@eecs.umich.edu 3817303Sgblack@eecs.umich.edudef template StoreCondMemAccExecute {{ 3827303Sgblack@eecs.umich.edu Fault 3837303Sgblack@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3847279Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 3857279Sgblack@eecs.umich.edu { 3867279Sgblack@eecs.umich.edu Addr EA; 3877279Sgblack@eecs.umich.edu Fault fault = NoFault; 3887279Sgblack@eecs.umich.edu uint64_t write_result = 0; 3897279Sgblack@eecs.umich.edu 3907279Sgblack@eecs.umich.edu %(fp_enable_check)s; 3917279Sgblack@eecs.umich.edu %(op_decl)s; 3927132Sgblack@eecs.umich.edu %(op_rd)s; 3937132Sgblack@eecs.umich.edu EA = xc->getEA(); 3947132Sgblack@eecs.umich.edu 3957132Sgblack@eecs.umich.edu if (fault == NoFault) { 3967132Sgblack@eecs.umich.edu %(memacc_code)s; 3977132Sgblack@eecs.umich.edu } 3987132Sgblack@eecs.umich.edu 3997132Sgblack@eecs.umich.edu if (fault == NoFault) { 4007132Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4017132Sgblack@eecs.umich.edu memAccessFlags, &write_result); 4027132Sgblack@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 4037132Sgblack@eecs.umich.edu } 4047132Sgblack@eecs.umich.edu 4057132Sgblack@eecs.umich.edu if (fault == NoFault) { 4067132Sgblack@eecs.umich.edu %(postacc_code)s; 4077132Sgblack@eecs.umich.edu } 4087132Sgblack@eecs.umich.edu 4097132Sgblack@eecs.umich.edu if (fault == NoFault) { 4107132Sgblack@eecs.umich.edu %(op_wb)s; 4117132Sgblack@eecs.umich.edu } 4127132Sgblack@eecs.umich.edu 4137132Sgblack@eecs.umich.edu return fault; 4147132Sgblack@eecs.umich.edu } 4157132Sgblack@eecs.umich.edu}}; 4167132Sgblack@eecs.umich.edu 4177132Sgblack@eecs.umich.edu 4187132Sgblack@eecs.umich.edudef template StoreExecute {{ 4197279Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4207279Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 4217279Sgblack@eecs.umich.edu { 4227279Sgblack@eecs.umich.edu Addr EA; 4237279Sgblack@eecs.umich.edu Fault fault = NoFault; 4247279Sgblack@eecs.umich.edu 4257279Sgblack@eecs.umich.edu %(fp_enable_check)s; 4267303Sgblack@eecs.umich.edu %(op_decl)s; 4277303Sgblack@eecs.umich.edu %(op_rd)s; 4287303Sgblack@eecs.umich.edu %(ea_code)s; 4297303Sgblack@eecs.umich.edu 4307303Sgblack@eecs.umich.edu if (fault == NoFault) { 4317303Sgblack@eecs.umich.edu %(memacc_code)s; 4327303Sgblack@eecs.umich.edu } 4337303Sgblack@eecs.umich.edu 4347279Sgblack@eecs.umich.edu if (fault == NoFault) { 4357279Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4367279Sgblack@eecs.umich.edu memAccessFlags, NULL); 4377279Sgblack@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 4387279Sgblack@eecs.umich.edu } 4397279Sgblack@eecs.umich.edu 4407279Sgblack@eecs.umich.edu if (fault == NoFault) { 4417279Sgblack@eecs.umich.edu %(postacc_code)s; 4427132Sgblack@eecs.umich.edu } 4437132Sgblack@eecs.umich.edu 4447132Sgblack@eecs.umich.edu if (fault == NoFault) { 4457132Sgblack@eecs.umich.edu %(op_wb)s; 4467132Sgblack@eecs.umich.edu } 4477132Sgblack@eecs.umich.edu 4487132Sgblack@eecs.umich.edu return fault; 4497132Sgblack@eecs.umich.edu } 4507132Sgblack@eecs.umich.edu}}; 4517132Sgblack@eecs.umich.edu 4527132Sgblack@eecs.umich.edudef template StoreCondExecute {{ 4537132Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4547132Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 4557132Sgblack@eecs.umich.edu { 4567118Sgblack@eecs.umich.edu Addr EA; 4577118Sgblack@eecs.umich.edu Fault fault = NoFault; 4587118Sgblack@eecs.umich.edu uint64_t write_result = 0; 4597118Sgblack@eecs.umich.edu 4607118Sgblack@eecs.umich.edu %(fp_enable_check)s; 4617132Sgblack@eecs.umich.edu %(op_decl)s; 4627118Sgblack@eecs.umich.edu %(op_rd)s; 4637118Sgblack@eecs.umich.edu %(ea_code)s; 4647118Sgblack@eecs.umich.edu 4657118Sgblack@eecs.umich.edu if (fault == NoFault) { 4667118Sgblack@eecs.umich.edu %(memacc_code)s; 4677118Sgblack@eecs.umich.edu } 4687118Sgblack@eecs.umich.edu 4697279Sgblack@eecs.umich.edu if (fault == NoFault) { 4707279Sgblack@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4717279Sgblack@eecs.umich.edu memAccessFlags, &write_result); 4727279Sgblack@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 4737279Sgblack@eecs.umich.edu } 4747279Sgblack@eecs.umich.edu 4757279Sgblack@eecs.umich.edu if (fault == NoFault) { 4767303Sgblack@eecs.umich.edu %(postacc_code)s; 4777303Sgblack@eecs.umich.edu } 4787303Sgblack@eecs.umich.edu 4797303Sgblack@eecs.umich.edu if (fault == NoFault) { 4807303Sgblack@eecs.umich.edu %(op_wb)s; 4817303Sgblack@eecs.umich.edu } 4827303Sgblack@eecs.umich.edu 4837303Sgblack@eecs.umich.edu return fault; 4847279Sgblack@eecs.umich.edu } 4857279Sgblack@eecs.umich.edu}}; 4867279Sgblack@eecs.umich.edu 4877279Sgblack@eecs.umich.edudef template StoreInitiateAcc {{ 4887279Sgblack@eecs.umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4897279Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 4907279Sgblack@eecs.umich.edu { 4917279Sgblack@eecs.umich.edu Addr EA; 4927118Sgblack@eecs.umich.edu Fault fault = NoFault; 4937118Sgblack@eecs.umich.edu 4947118Sgblack@eecs.umich.edu %(fp_enable_check)s; 4957118Sgblack@eecs.umich.edu %(op_decl)s; 4967132Sgblack@eecs.umich.edu %(op_rd)s; 4977118Sgblack@eecs.umich.edu %(ea_code)s; 4987118Sgblack@eecs.umich.edu 4997118Sgblack@eecs.umich.edu if (fault == NoFault) { 5006253Sgblack@eecs.umich.edu %(memacc_code)s; 5016253Sgblack@eecs.umich.edu } 5026253Sgblack@eecs.umich.edu 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->getExtraData(); 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