mem.isa revision 8607
111308Santhony.gutierrez@amd.com// -*- mode:c++ -*- 211308Santhony.gutierrez@amd.com 311308Santhony.gutierrez@amd.com// Copyright (c) 2003-2005 The Regents of The University of Michigan 411308Santhony.gutierrez@amd.com// All rights reserved. 511308Santhony.gutierrez@amd.com// 611308Santhony.gutierrez@amd.com// Redistribution and use in source and binary forms, with or without 711308Santhony.gutierrez@amd.com// modification, are permitted provided that the following conditions are 811308Santhony.gutierrez@amd.com// met: redistributions of source code must retain the above copyright 911308Santhony.gutierrez@amd.com// notice, this list of conditions and the following disclaimer; 1011308Santhony.gutierrez@amd.com// redistributions in binary form must reproduce the above copyright 1111308Santhony.gutierrez@amd.com// notice, this list of conditions and the following disclaimer in the 1211308Santhony.gutierrez@amd.com// documentation and/or other materials provided with the distribution; 1311308Santhony.gutierrez@amd.com// neither the name of the copyright holders nor the names of its 1411308Santhony.gutierrez@amd.com// contributors may be used to endorse or promote products derived from 1511308Santhony.gutierrez@amd.com// this software without specific prior written permission. 1611308Santhony.gutierrez@amd.com// 1711308Santhony.gutierrez@amd.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1811308Santhony.gutierrez@amd.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1911308Santhony.gutierrez@amd.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2011308Santhony.gutierrez@amd.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2111308Santhony.gutierrez@amd.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2211308Santhony.gutierrez@amd.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2311308Santhony.gutierrez@amd.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2411308Santhony.gutierrez@amd.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2511308Santhony.gutierrez@amd.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2611308Santhony.gutierrez@amd.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2711308Santhony.gutierrez@amd.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811308Santhony.gutierrez@amd.com// 2911308Santhony.gutierrez@amd.com// Authors: Steve Reinhardt 3011308Santhony.gutierrez@amd.com// Kevin Lim 3111308Santhony.gutierrez@amd.com 3211308Santhony.gutierrez@amd.com//////////////////////////////////////////////////////////////////// 3311308Santhony.gutierrez@amd.com// 3411308Santhony.gutierrez@amd.com// Memory-format instructions: LoadAddress, Load, Store 3511308Santhony.gutierrez@amd.com// 3611308Santhony.gutierrez@amd.com 3711308Santhony.gutierrez@amd.comoutput header {{ 3811308Santhony.gutierrez@amd.com /** 3911308Santhony.gutierrez@amd.com * Base class for general Alpha memory-format instructions. 4011308Santhony.gutierrez@amd.com */ 4111308Santhony.gutierrez@amd.com class Memory : public AlphaStaticInst 4211308Santhony.gutierrez@amd.com { 4311670Sandreas.hansson@arm.com protected: 4411670Sandreas.hansson@arm.com 4511308Santhony.gutierrez@amd.com /// Memory request flags. See mem_req_base.hh. 4611308Santhony.gutierrez@amd.com Request::Flags memAccessFlags; 4711308Santhony.gutierrez@amd.com 4811308Santhony.gutierrez@amd.com /// Constructor 4911308Santhony.gutierrez@amd.com Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 5011308Santhony.gutierrez@amd.com : AlphaStaticInst(mnem, _machInst, __opClass) 5111308Santhony.gutierrez@amd.com { 5211308Santhony.gutierrez@amd.com } 5311308Santhony.gutierrez@amd.com 5411308Santhony.gutierrez@amd.com std::string 5511308Santhony.gutierrez@amd.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5611308Santhony.gutierrez@amd.com }; 5711308Santhony.gutierrez@amd.com 5811308Santhony.gutierrez@amd.com /** 5911308Santhony.gutierrez@amd.com * Base class for memory-format instructions using a 32-bit 6011308Santhony.gutierrez@amd.com * displacement (i.e. most of them). 6111308Santhony.gutierrez@amd.com */ 6211308Santhony.gutierrez@amd.com class MemoryDisp32 : public Memory 6311308Santhony.gutierrez@amd.com { 6411308Santhony.gutierrez@amd.com protected: 6511308Santhony.gutierrez@amd.com /// Displacement for EA calculation (signed). 6611308Santhony.gutierrez@amd.com int32_t disp; 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com /// Constructor. 6911308Santhony.gutierrez@amd.com MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 7011308Santhony.gutierrez@amd.com : Memory(mnem, _machInst, __opClass), 7111308Santhony.gutierrez@amd.com disp(MEMDISP) 7211308Santhony.gutierrez@amd.com { 7311308Santhony.gutierrez@amd.com } 7411308Santhony.gutierrez@amd.com }; 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.com /** 7811308Santhony.gutierrez@amd.com * Base class for a few miscellaneous memory-format insts 7911308Santhony.gutierrez@amd.com * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 8011308Santhony.gutierrez@amd.com * None of these instructions has a destination register either. 8111308Santhony.gutierrez@amd.com */ 8211308Santhony.gutierrez@amd.com class MemoryNoDisp : public Memory 8311308Santhony.gutierrez@amd.com { 8411308Santhony.gutierrez@amd.com protected: 8511308Santhony.gutierrez@amd.com /// Constructor 8611308Santhony.gutierrez@amd.com MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 8711308Santhony.gutierrez@amd.com : Memory(mnem, _machInst, __opClass) 8811308Santhony.gutierrez@amd.com { 8911308Santhony.gutierrez@amd.com } 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com std::string 9211308Santhony.gutierrez@amd.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 9311308Santhony.gutierrez@amd.com }; 9411308Santhony.gutierrez@amd.com}}; 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.com 9711308Santhony.gutierrez@amd.comoutput decoder {{ 9811308Santhony.gutierrez@amd.com std::string 9911308Santhony.gutierrez@amd.com Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 10011308Santhony.gutierrez@amd.com { 10111308Santhony.gutierrez@amd.com return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 10211308Santhony.gutierrez@amd.com flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 10311308Santhony.gutierrez@amd.com } 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com std::string 10611308Santhony.gutierrez@amd.com MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 10711308Santhony.gutierrez@amd.com { 10811308Santhony.gutierrez@amd.com return csprintf("%-10s (r%d)", mnemonic, RB); 10911308Santhony.gutierrez@amd.com } 11011308Santhony.gutierrez@amd.com}}; 11111308Santhony.gutierrez@amd.com 11211308Santhony.gutierrez@amd.comdef format LoadAddress(code) {{ 11311308Santhony.gutierrez@amd.com iop = InstObjParams(name, Name, 'MemoryDisp32', code) 11411308Santhony.gutierrez@amd.com header_output = BasicDeclare.subst(iop) 11511308Santhony.gutierrez@amd.com decoder_output = BasicConstructor.subst(iop) 11611308Santhony.gutierrez@amd.com decode_block = BasicDecode.subst(iop) 11711308Santhony.gutierrez@amd.com exec_output = BasicExecute.subst(iop) 11811308Santhony.gutierrez@amd.com}}; 11911308Santhony.gutierrez@amd.com 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.comdef template LoadStoreDeclare {{ 12211308Santhony.gutierrez@amd.com /** 12311308Santhony.gutierrez@amd.com * Static instruction class for "%(mnemonic)s". 12411308Santhony.gutierrez@amd.com */ 12511308Santhony.gutierrez@amd.com class %(class_name)s : public %(base_class)s 12611308Santhony.gutierrez@amd.com { 12711308Santhony.gutierrez@amd.com public: 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.com /// Constructor. 13011308Santhony.gutierrez@amd.com %(class_name)s(ExtMachInst machInst); 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com %(BasicExecDeclare)s 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com %(EACompDeclare)s 13511308Santhony.gutierrez@amd.com 13611308Santhony.gutierrez@amd.com %(InitiateAccDeclare)s 13711308Santhony.gutierrez@amd.com 13811308Santhony.gutierrez@amd.com %(CompleteAccDeclare)s 13911308Santhony.gutierrez@amd.com }; 14011308Santhony.gutierrez@amd.com}}; 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com 14311308Santhony.gutierrez@amd.comdef template EACompDeclare {{ 14411308Santhony.gutierrez@amd.com Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const; 14511308Santhony.gutierrez@amd.com}}; 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.comdef template InitiateAccDeclare {{ 14811308Santhony.gutierrez@amd.com Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 14911308Santhony.gutierrez@amd.com}}; 15011308Santhony.gutierrez@amd.com 15111308Santhony.gutierrez@amd.com 15211308Santhony.gutierrez@amd.comdef template CompleteAccDeclare {{ 15311308Santhony.gutierrez@amd.com Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 15411308Santhony.gutierrez@amd.com Trace::InstRecord *) const; 15511308Santhony.gutierrez@amd.com}}; 15611308Santhony.gutierrez@amd.com 15711308Santhony.gutierrez@amd.comdef template LoadStoreConstructor {{ 15811308Santhony.gutierrez@amd.com inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 15911308Santhony.gutierrez@amd.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 16011308Santhony.gutierrez@amd.com { 16111308Santhony.gutierrez@amd.com %(constructor)s; 16211308Santhony.gutierrez@amd.com } 16311308Santhony.gutierrez@amd.com}}; 16411308Santhony.gutierrez@amd.com 16511308Santhony.gutierrez@amd.comdef template EACompExecute {{ 16611308Santhony.gutierrez@amd.com Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc, 16711308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 16811308Santhony.gutierrez@amd.com { 16911308Santhony.gutierrez@amd.com Addr EA; 17012065Snikos.nikoleris@arm.com Fault fault = NoFault; 17111308Santhony.gutierrez@amd.com 17211308Santhony.gutierrez@amd.com %(fp_enable_check)s; 17311308Santhony.gutierrez@amd.com %(op_decl)s; 17411308Santhony.gutierrez@amd.com %(op_rd)s; 17512065Snikos.nikoleris@arm.com %(ea_code)s; 17612065Snikos.nikoleris@arm.com 17711308Santhony.gutierrez@amd.com if (fault == NoFault) { 17811308Santhony.gutierrez@amd.com %(op_wb)s; 17911308Santhony.gutierrez@amd.com xc->setEA(EA); 18011308Santhony.gutierrez@amd.com } 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com return fault; 18311308Santhony.gutierrez@amd.com } 18411308Santhony.gutierrez@amd.com}}; 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com 18711308Santhony.gutierrez@amd.comdef template LoadExecute {{ 18811308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 18911308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 19011308Santhony.gutierrez@amd.com { 19111308Santhony.gutierrez@amd.com Addr EA; 19211308Santhony.gutierrez@amd.com Fault fault = NoFault; 19311308Santhony.gutierrez@amd.com 19411308Santhony.gutierrez@amd.com %(fp_enable_check)s; 19511308Santhony.gutierrez@amd.com %(op_decl)s; 19611308Santhony.gutierrez@amd.com %(op_rd)s; 19711308Santhony.gutierrez@amd.com %(ea_code)s; 19811308Santhony.gutierrez@amd.com 19911308Santhony.gutierrez@amd.com if (fault == NoFault) { 20011308Santhony.gutierrez@amd.com fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 20111308Santhony.gutierrez@amd.com %(memacc_code)s; 20211308Santhony.gutierrez@amd.com } 20311308Santhony.gutierrez@amd.com 20411308Santhony.gutierrez@amd.com if (fault == NoFault) { 20511308Santhony.gutierrez@amd.com %(op_wb)s; 20611308Santhony.gutierrez@amd.com } 20711308Santhony.gutierrez@amd.com 20811308Santhony.gutierrez@amd.com return fault; 20911308Santhony.gutierrez@amd.com } 21011308Santhony.gutierrez@amd.com}}; 21111308Santhony.gutierrez@amd.com 21212598Snikos.nikoleris@arm.com 21312598Snikos.nikoleris@arm.comdef template LoadInitiateAcc {{ 21411308Santhony.gutierrez@amd.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 21511308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 21611308Santhony.gutierrez@amd.com { 21711308Santhony.gutierrez@amd.com Addr EA; 21811308Santhony.gutierrez@amd.com Fault fault = NoFault; 21911308Santhony.gutierrez@amd.com 22011308Santhony.gutierrez@amd.com %(fp_enable_check)s; 22111308Santhony.gutierrez@amd.com %(op_src_decl)s; 22211308Santhony.gutierrez@amd.com %(op_rd)s; 22311308Santhony.gutierrez@amd.com %(ea_code)s; 22411308Santhony.gutierrez@amd.com 22511308Santhony.gutierrez@amd.com if (fault == NoFault) { 22611308Santhony.gutierrez@amd.com fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); 22711308Santhony.gutierrez@amd.com } 22811308Santhony.gutierrez@amd.com 22911308Santhony.gutierrez@amd.com return fault; 23011308Santhony.gutierrez@amd.com } 23111308Santhony.gutierrez@amd.com}}; 23211308Santhony.gutierrez@amd.com 23311308Santhony.gutierrez@amd.com 23411308Santhony.gutierrez@amd.comdef template LoadCompleteAcc {{ 23511308Santhony.gutierrez@amd.com Fault %(class_name)s::completeAcc(PacketPtr pkt, 23611308Santhony.gutierrez@amd.com %(CPU_exec_context)s *xc, 23711308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 23811308Santhony.gutierrez@amd.com { 23912065Snikos.nikoleris@arm.com Fault fault = NoFault; 24012065Snikos.nikoleris@arm.com 24112065Snikos.nikoleris@arm.com %(fp_enable_check)s; 24212065Snikos.nikoleris@arm.com %(op_decl)s; 24312065Snikos.nikoleris@arm.com 24412065Snikos.nikoleris@arm.com getMem(pkt, Mem, traceData); 24512065Snikos.nikoleris@arm.com 24612065Snikos.nikoleris@arm.com if (fault == NoFault) { 24712065Snikos.nikoleris@arm.com %(memacc_code)s; 24812065Snikos.nikoleris@arm.com } 24912065Snikos.nikoleris@arm.com 25011308Santhony.gutierrez@amd.com if (fault == NoFault) { 25112065Snikos.nikoleris@arm.com %(op_wb)s; 25212065Snikos.nikoleris@arm.com } 25312065Snikos.nikoleris@arm.com 25412065Snikos.nikoleris@arm.com return fault; 25512065Snikos.nikoleris@arm.com } 25612065Snikos.nikoleris@arm.com}}; 25712065Snikos.nikoleris@arm.com 25812065Snikos.nikoleris@arm.com 25911308Santhony.gutierrez@amd.comdef template StoreExecute {{ 26011308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 26112065Snikos.nikoleris@arm.com Trace::InstRecord *traceData) const 26211308Santhony.gutierrez@amd.com { 26311308Santhony.gutierrez@amd.com Addr EA; 26411308Santhony.gutierrez@amd.com Fault fault = NoFault; 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com %(fp_enable_check)s; 26711308Santhony.gutierrez@amd.com %(op_decl)s; 26811308Santhony.gutierrez@amd.com %(op_rd)s; 26911308Santhony.gutierrez@amd.com %(ea_code)s; 27011308Santhony.gutierrez@amd.com 27111308Santhony.gutierrez@amd.com if (fault == NoFault) { 27211308Santhony.gutierrez@amd.com %(memacc_code)s; 27311308Santhony.gutierrez@amd.com } 27411308Santhony.gutierrez@amd.com 27511308Santhony.gutierrez@amd.com if (fault == NoFault) { 27611308Santhony.gutierrez@amd.com fault = writeMemAtomic(xc, traceData, Mem, EA, 27711308Santhony.gutierrez@amd.com memAccessFlags, NULL); 27811308Santhony.gutierrez@amd.com } 27911308Santhony.gutierrez@amd.com 28011308Santhony.gutierrez@amd.com if (fault == NoFault) { 28111308Santhony.gutierrez@amd.com %(postacc_code)s; 28211308Santhony.gutierrez@amd.com } 28311308Santhony.gutierrez@amd.com 28411308Santhony.gutierrez@amd.com if (fault == NoFault) { 28511308Santhony.gutierrez@amd.com %(op_wb)s; 28611308Santhony.gutierrez@amd.com } 28711308Santhony.gutierrez@amd.com 28811308Santhony.gutierrez@amd.com return fault; 28911308Santhony.gutierrez@amd.com } 29011308Santhony.gutierrez@amd.com}}; 29111308Santhony.gutierrez@amd.com 29211308Santhony.gutierrez@amd.comdef template StoreCondExecute {{ 29311308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 29411308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 29511308Santhony.gutierrez@amd.com { 29611308Santhony.gutierrez@amd.com Addr EA; 29711308Santhony.gutierrez@amd.com Fault fault = NoFault; 29811308Santhony.gutierrez@amd.com uint64_t write_result = 0; 29911308Santhony.gutierrez@amd.com 30011308Santhony.gutierrez@amd.com %(fp_enable_check)s; 30111308Santhony.gutierrez@amd.com %(op_decl)s; 30211308Santhony.gutierrez@amd.com %(op_rd)s; 30311308Santhony.gutierrez@amd.com %(ea_code)s; 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.com if (fault == NoFault) { 30611308Santhony.gutierrez@amd.com %(memacc_code)s; 30711308Santhony.gutierrez@amd.com } 30811308Santhony.gutierrez@amd.com 30911308Santhony.gutierrez@amd.com if (fault == NoFault) { 31011308Santhony.gutierrez@amd.com fault = writeMemAtomic(xc, traceData, Mem, EA, 31111308Santhony.gutierrez@amd.com memAccessFlags, &write_result); 31211308Santhony.gutierrez@amd.com } 31311308Santhony.gutierrez@amd.com 31411308Santhony.gutierrez@amd.com if (fault == NoFault) { 31511308Santhony.gutierrez@amd.com %(postacc_code)s; 31611308Santhony.gutierrez@amd.com } 31711308Santhony.gutierrez@amd.com 31811308Santhony.gutierrez@amd.com if (fault == NoFault) { 31911308Santhony.gutierrez@amd.com %(op_wb)s; 32011308Santhony.gutierrez@amd.com } 32111308Santhony.gutierrez@amd.com 32211308Santhony.gutierrez@amd.com return fault; 32311308Santhony.gutierrez@amd.com } 32411308Santhony.gutierrez@amd.com}}; 32511308Santhony.gutierrez@amd.com 32611308Santhony.gutierrez@amd.comdef template StoreInitiateAcc {{ 32711308Santhony.gutierrez@amd.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 32811308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 32911308Santhony.gutierrez@amd.com { 33011308Santhony.gutierrez@amd.com Addr EA; 33111308Santhony.gutierrez@amd.com Fault fault = NoFault; 33211308Santhony.gutierrez@amd.com 33311308Santhony.gutierrez@amd.com %(fp_enable_check)s; 33411308Santhony.gutierrez@amd.com %(op_decl)s; 33511308Santhony.gutierrez@amd.com %(op_rd)s; 33611308Santhony.gutierrez@amd.com %(ea_code)s; 337 338 if (fault == NoFault) { 339 %(memacc_code)s; 340 } 341 342 if (fault == NoFault) { 343 fault = writeMemTiming(xc, traceData, Mem, EA, 344 memAccessFlags, NULL); 345 } 346 347 return fault; 348 } 349}}; 350 351 352def template StoreCompleteAcc {{ 353 Fault %(class_name)s::completeAcc(PacketPtr pkt, 354 %(CPU_exec_context)s *xc, 355 Trace::InstRecord *traceData) const 356 { 357 return NoFault; 358 } 359}}; 360 361 362def template StoreCondCompleteAcc {{ 363 Fault %(class_name)s::completeAcc(PacketPtr pkt, 364 %(CPU_exec_context)s *xc, 365 Trace::InstRecord *traceData) const 366 { 367 Fault fault = NoFault; 368 369 %(fp_enable_check)s; 370 %(op_dest_decl)s; 371 372 uint64_t write_result = pkt->req->getExtraData(); 373 374 if (fault == NoFault) { 375 %(postacc_code)s; 376 } 377 378 if (fault == NoFault) { 379 %(op_wb)s; 380 } 381 382 return fault; 383 } 384}}; 385 386 387def template MiscExecute {{ 388 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 389 Trace::InstRecord *traceData) const 390 { 391 Addr EA M5_VAR_USED; 392 Fault fault = NoFault; 393 394 %(fp_enable_check)s; 395 %(op_decl)s; 396 %(op_rd)s; 397 %(ea_code)s; 398 399 warn_once("Prefetch instructions in Alpha do not do anything\n"); 400 if (fault == NoFault) { 401 %(memacc_code)s; 402 } 403 404 return NoFault; 405 } 406}}; 407 408// Prefetches in Alpha don't actually do anything 409// They just build an effective address and complete 410def template MiscInitiateAcc {{ 411 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 412 Trace::InstRecord *traceData) const 413 { 414 warn("initiateAcc undefined: Misc instruction does not support split " 415 "access method!"); 416 return NoFault; 417 } 418}}; 419 420 421def template MiscCompleteAcc {{ 422 Fault %(class_name)s::completeAcc(PacketPtr pkt, 423 %(CPU_exec_context)s *xc, 424 Trace::InstRecord *traceData) const 425 { 426 warn("completeAcc undefined: Misc instruction does not support split " 427 "access method!"); 428 429 return NoFault; 430 } 431}}; 432 433 434// load instructions use Ra as dest, so check for 435// Ra == 31 to detect nops 436def template LoadNopCheckDecode {{ 437 { 438 AlphaStaticInst *i = new %(class_name)s(machInst); 439 if (RA == 31) { 440 i = makeNop(i); 441 } 442 return i; 443 } 444}}; 445 446 447// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 448def template LoadPrefetchCheckDecode {{ 449 { 450 if (RA != 31) { 451 return new %(class_name)s(machInst); 452 } 453 else { 454 return new %(class_name)sPrefetch(machInst); 455 } 456 } 457}}; 458 459 460let {{ 461def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 462 postacc_code = '', base_class = 'MemoryDisp32', 463 decode_template = BasicDecode, exec_template_base = ''): 464 # Make sure flags are in lists (convert to lists if not). 465 mem_flags = makeList(mem_flags) 466 inst_flags = makeList(inst_flags) 467 468 # Some CPU models execute the memory operation as an atomic unit, 469 # while others want to separate them into an effective address 470 # computation and a memory access operation. As a result, we need 471 # to generate three StaticInst objects. Note that the latter two 472 # are nested inside the larger "atomic" one. 473 474 # Generate InstObjParams for each of the three objects. Note that 475 # they differ only in the set of code objects contained (which in 476 # turn affects the object's overall operand list). 477 iop = InstObjParams(name, Name, base_class, 478 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 479 inst_flags) 480 memacc_iop = InstObjParams(name, Name, base_class, 481 { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 482 inst_flags) 483 484 if mem_flags: 485 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 486 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 487 iop.constructor += s 488 memacc_iop.constructor += s 489 490 # select templates 491 492 # The InitiateAcc template is the same for StoreCond templates as the 493 # corresponding Store template.. 494 StoreCondInitiateAcc = StoreInitiateAcc 495 496 fullExecTemplate = eval(exec_template_base + 'Execute') 497 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 498 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 499 500 # (header_output, decoder_output, decode_block, exec_output) 501 return (LoadStoreDeclare.subst(iop), 502 LoadStoreConstructor.subst(iop), 503 decode_template.subst(iop), 504 fullExecTemplate.subst(iop) 505 + EACompExecute.subst(iop) 506 + initiateAccTemplate.subst(iop) 507 + completeAccTemplate.subst(iop)) 508}}; 509 510def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 511 mem_flags = [], inst_flags = []) {{ 512 (header_output, decoder_output, decode_block, exec_output) = \ 513 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 514 decode_template = LoadNopCheckDecode, 515 exec_template_base = 'Load') 516}}; 517 518 519// Note that the flags passed in apply only to the prefetch version 520def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 521 mem_flags = [], pf_flags = [], inst_flags = []) {{ 522 # declare the load instruction object and generate the decode block 523 (header_output, decoder_output, decode_block, exec_output) = \ 524 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 525 decode_template = LoadPrefetchCheckDecode, 526 exec_template_base = 'Load') 527 528 # Declare the prefetch instruction object. 529 530 # Make sure flag args are lists so we can mess with them. 531 mem_flags = makeList(mem_flags) 532 pf_flags = makeList(pf_flags) 533 inst_flags = makeList(inst_flags) 534 535 pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] 536 pf_inst_flags = inst_flags 537 538 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 539 LoadStoreBase(name, Name + 'Prefetch', ea_code, ';', 540 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 541 542 header_output += pf_header_output 543 decoder_output += pf_decoder_output 544 exec_output += pf_exec_output 545}}; 546 547 548def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 549 mem_flags = [], inst_flags = []) {{ 550 (header_output, decoder_output, decode_block, exec_output) = \ 551 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 552 exec_template_base = 'Store') 553}}; 554 555 556def format StoreCond(memacc_code, postacc_code, 557 ea_code = {{ EA = Rb + disp; }}, 558 mem_flags = [], inst_flags = []) {{ 559 (header_output, decoder_output, decode_block, exec_output) = \ 560 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 561 postacc_code, exec_template_base = 'StoreCond') 562}}; 563 564 565// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 566def format MiscPrefetch(ea_code, memacc_code, 567 mem_flags = [], inst_flags = []) {{ 568 (header_output, decoder_output, decode_block, exec_output) = \ 569 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 570 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 571}}; 572 573 574