mem.isa revision 8442
111308Santhony.gutierrez@amd.com// -*- mode:c++ -*- 211308Santhony.gutierrez@amd.com 311308Santhony.gutierrez@amd.com// Copyright (c) 2007 MIPS Technologies, Inc. 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// Korey Sewell 3111308Santhony.gutierrez@amd.com 3211308Santhony.gutierrez@amd.com//////////////////////////////////////////////////////////////////// 3311308Santhony.gutierrez@amd.com// 3411308Santhony.gutierrez@amd.com// Memory-format instructions 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 Mips memory-format instructions. 4011308Santhony.gutierrez@amd.com */ 4111308Santhony.gutierrez@amd.com class Memory : public MipsStaticInst 4211308Santhony.gutierrez@amd.com { 4311670Sandreas.hansson@arm.com protected: 4411670Sandreas.hansson@arm.com /// Memory request flags. See mem_req_base.hh. 4511308Santhony.gutierrez@amd.com Request::Flags memAccessFlags; 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.com /// Displacement for EA calculation (signed). 4811308Santhony.gutierrez@amd.com int32_t disp; 4911308Santhony.gutierrez@amd.com 5011308Santhony.gutierrez@amd.com /// Constructor 5111308Santhony.gutierrez@amd.com Memory(const char *mnem, MachInst _machInst, OpClass __opClass) 5211308Santhony.gutierrez@amd.com : MipsStaticInst(mnem, _machInst, __opClass), 5311308Santhony.gutierrez@amd.com disp(sext<16>(OFFSET)) 5411308Santhony.gutierrez@amd.com { 5511308Santhony.gutierrez@amd.com } 5611308Santhony.gutierrez@amd.com 5711308Santhony.gutierrez@amd.com std::string 5811308Santhony.gutierrez@amd.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5911308Santhony.gutierrez@amd.com }; 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.com /** 6211308Santhony.gutierrez@amd.com * Base class for a few miscellaneous memory-format insts 6311308Santhony.gutierrez@amd.com * that don't interpret the disp field 6411308Santhony.gutierrez@amd.com */ 6511308Santhony.gutierrez@amd.com class MemoryNoDisp : public Memory 6611308Santhony.gutierrez@amd.com { 6711308Santhony.gutierrez@amd.com protected: 6811308Santhony.gutierrez@amd.com /// Constructor 6911308Santhony.gutierrez@amd.com MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 7011308Santhony.gutierrez@amd.com : Memory(mnem, _machInst, __opClass) 7111308Santhony.gutierrez@amd.com { 7211308Santhony.gutierrez@amd.com } 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com std::string 7511308Santhony.gutierrez@amd.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 7611308Santhony.gutierrez@amd.com }; 7711308Santhony.gutierrez@amd.com}}; 7811308Santhony.gutierrez@amd.com 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.comoutput decoder {{ 8111308Santhony.gutierrez@amd.com std::string 8211308Santhony.gutierrez@amd.com Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 8311308Santhony.gutierrez@amd.com { 8411308Santhony.gutierrez@amd.com return csprintf("%-10s %c%d, %d(r%d)", mnemonic, 8511308Santhony.gutierrez@amd.com flags[IsFloating] ? 'f' : 'r', RT, disp, RS); 8611308Santhony.gutierrez@amd.com } 8711308Santhony.gutierrez@amd.com 8811308Santhony.gutierrez@amd.com std::string 8911308Santhony.gutierrez@amd.com MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 9011308Santhony.gutierrez@amd.com { 9111308Santhony.gutierrez@amd.com return csprintf("%-10s %c%d, r%d(r%d)", mnemonic, 9211308Santhony.gutierrez@amd.com flags[IsFloating] ? 'f' : 'r', 9311308Santhony.gutierrez@amd.com flags[IsFloating] ? FD : RD, 9411308Santhony.gutierrez@amd.com RS, RT); 9511308Santhony.gutierrez@amd.com } 9611308Santhony.gutierrez@amd.com 9711308Santhony.gutierrez@amd.com}}; 9811308Santhony.gutierrez@amd.com 9911308Santhony.gutierrez@amd.comoutput exec {{ 10011308Santhony.gutierrez@amd.com /** return data in cases where there the size of data is only 10111308Santhony.gutierrez@amd.com known in the packet 10211308Santhony.gutierrez@amd.com */ 10311308Santhony.gutierrez@amd.com uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) { 10411308Santhony.gutierrez@amd.com switch (packet->getSize()) 10511308Santhony.gutierrez@amd.com { 10611308Santhony.gutierrez@amd.com case 1: 10711308Santhony.gutierrez@amd.com return packet->get<uint8_t>(); 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com case 2: 11011308Santhony.gutierrez@amd.com return packet->get<uint16_t>(); 11111308Santhony.gutierrez@amd.com 11211308Santhony.gutierrez@amd.com case 4: 11311308Santhony.gutierrez@amd.com return packet->get<uint32_t>(); 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.com case 8: 11611308Santhony.gutierrez@amd.com return packet->get<uint64_t>(); 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.com default: 11911308Santhony.gutierrez@amd.com std::cerr << "bad store data size = " << packet->getSize() << std::endl; 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com assert(0); 12211308Santhony.gutierrez@amd.com return 0; 12311308Santhony.gutierrez@amd.com } 12411308Santhony.gutierrez@amd.com } 12511308Santhony.gutierrez@amd.com 12611308Santhony.gutierrez@amd.com 12711308Santhony.gutierrez@amd.com}}; 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.comdef template LoadStoreDeclare {{ 13011308Santhony.gutierrez@amd.com /** 13111308Santhony.gutierrez@amd.com * Static instruction class for "%(mnemonic)s". 13211308Santhony.gutierrez@amd.com */ 13311308Santhony.gutierrez@amd.com class %(class_name)s : public %(base_class)s 13411308Santhony.gutierrez@amd.com { 13511308Santhony.gutierrez@amd.com public: 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com /// Constructor. 13811308Santhony.gutierrez@amd.com %(class_name)s(ExtMachInst machInst); 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com %(BasicExecDeclare)s 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com %(EACompDeclare)s 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.com %(InitiateAccDeclare)s 14511308Santhony.gutierrez@amd.com 14611308Santhony.gutierrez@amd.com %(CompleteAccDeclare)s 14711308Santhony.gutierrez@amd.com }; 14811308Santhony.gutierrez@amd.com}}; 14911308Santhony.gutierrez@amd.com 15011308Santhony.gutierrez@amd.comdef template EACompDeclare {{ 15111308Santhony.gutierrez@amd.com Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const; 15211308Santhony.gutierrez@amd.com}}; 15311308Santhony.gutierrez@amd.com 15411308Santhony.gutierrez@amd.comdef template InitiateAccDeclare {{ 15511308Santhony.gutierrez@amd.com Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 15611308Santhony.gutierrez@amd.com}}; 15711308Santhony.gutierrez@amd.com 15811308Santhony.gutierrez@amd.com 15911308Santhony.gutierrez@amd.comdef template CompleteAccDeclare {{ 16011308Santhony.gutierrez@amd.com Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 16111308Santhony.gutierrez@amd.com}}; 16211308Santhony.gutierrez@amd.com 16311308Santhony.gutierrez@amd.comdef template LoadStoreConstructor {{ 16411308Santhony.gutierrez@amd.com inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 16511308Santhony.gutierrez@amd.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 16611308Santhony.gutierrez@amd.com { 16711308Santhony.gutierrez@amd.com %(constructor)s; 16811308Santhony.gutierrez@amd.com } 16911308Santhony.gutierrez@amd.com}}; 17011308Santhony.gutierrez@amd.com 17111308Santhony.gutierrez@amd.com 17211308Santhony.gutierrez@amd.comdef template EACompExecute {{ 17311308Santhony.gutierrez@amd.com Fault 17411308Santhony.gutierrez@amd.com %(class_name)s::eaComp(%(CPU_exec_context)s *xc, 17511308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 17611308Santhony.gutierrez@amd.com { 17711308Santhony.gutierrez@amd.com Addr EA; 17811308Santhony.gutierrez@amd.com Fault fault = NoFault; 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.com if (this->isFloating()) { 18111308Santhony.gutierrez@amd.com %(fp_enable_check)s; 18211308Santhony.gutierrez@amd.com 18311308Santhony.gutierrez@amd.com if(fault != NoFault) 18411308Santhony.gutierrez@amd.com return fault; 18511308Santhony.gutierrez@amd.com } 18611308Santhony.gutierrez@amd.com 18711308Santhony.gutierrez@amd.com %(op_decl)s; 18811308Santhony.gutierrez@amd.com %(op_rd)s; 18911308Santhony.gutierrez@amd.com %(ea_code)s; 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.com // NOTE: Trace Data is written using execute or completeAcc templates 19211308Santhony.gutierrez@amd.com if (fault == NoFault) { 19311308Santhony.gutierrez@amd.com xc->setEA(EA); 19411308Santhony.gutierrez@amd.com } 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com return fault; 19711308Santhony.gutierrez@amd.com } 19811308Santhony.gutierrez@amd.com}}; 19911308Santhony.gutierrez@amd.com 20011308Santhony.gutierrez@amd.comdef template LoadExecute {{ 20111308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 20211308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 20311308Santhony.gutierrez@amd.com { 20411308Santhony.gutierrez@amd.com Addr EA; 20511308Santhony.gutierrez@amd.com Fault fault = NoFault; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com if (this->isFloating()) { 20811308Santhony.gutierrez@amd.com %(fp_enable_check)s; 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com if(fault != NoFault) 21111308Santhony.gutierrez@amd.com return fault; 21211308Santhony.gutierrez@amd.com } 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com %(op_decl)s; 21511308Santhony.gutierrez@amd.com %(op_rd)s; 21611308Santhony.gutierrez@amd.com %(ea_code)s; 21711308Santhony.gutierrez@amd.com 21811308Santhony.gutierrez@amd.com if (fault == NoFault) { 21911308Santhony.gutierrez@amd.com fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 22011308Santhony.gutierrez@amd.com %(memacc_code)s; 22111308Santhony.gutierrez@amd.com } 22211308Santhony.gutierrez@amd.com 22311308Santhony.gutierrez@amd.com if (fault == NoFault) { 22411308Santhony.gutierrez@amd.com %(op_wb)s; 22511308Santhony.gutierrez@amd.com } 22611308Santhony.gutierrez@amd.com 22711308Santhony.gutierrez@amd.com return fault; 22811308Santhony.gutierrez@amd.com } 22911308Santhony.gutierrez@amd.com}}; 23011308Santhony.gutierrez@amd.com 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.comdef template LoadInitiateAcc {{ 23311308Santhony.gutierrez@amd.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 23411308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 23511308Santhony.gutierrez@amd.com { 23611308Santhony.gutierrez@amd.com Addr EA; 23711308Santhony.gutierrez@amd.com Fault fault = NoFault; 23811308Santhony.gutierrez@amd.com 23911308Santhony.gutierrez@amd.com if (this->isFloating()) { 24011308Santhony.gutierrez@amd.com %(fp_enable_check)s; 24111308Santhony.gutierrez@amd.com 24211308Santhony.gutierrez@amd.com if(fault != NoFault) 24311308Santhony.gutierrez@amd.com return fault; 24411308Santhony.gutierrez@amd.com } 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com %(op_src_decl)s; 24711308Santhony.gutierrez@amd.com %(op_rd)s; 24811308Santhony.gutierrez@amd.com %(ea_code)s; 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com if (fault == NoFault) { 25111308Santhony.gutierrez@amd.com fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); 25211308Santhony.gutierrez@amd.com } 25311308Santhony.gutierrez@amd.com 25411308Santhony.gutierrez@amd.com return fault; 25511308Santhony.gutierrez@amd.com } 25611308Santhony.gutierrez@amd.com}}; 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.comdef template LoadCompleteAcc {{ 25911308Santhony.gutierrez@amd.com Fault %(class_name)s::completeAcc(Packet *pkt, 26011308Santhony.gutierrez@amd.com %(CPU_exec_context)s *xc, 26111308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 26211308Santhony.gutierrez@amd.com { 26311308Santhony.gutierrez@amd.com Fault fault = NoFault; 26411308Santhony.gutierrez@amd.com 26511308Santhony.gutierrez@amd.com if (this->isFloating()) { 26611308Santhony.gutierrez@amd.com %(fp_enable_check)s; 26711308Santhony.gutierrez@amd.com 26811308Santhony.gutierrez@amd.com if(fault != NoFault) 26911308Santhony.gutierrez@amd.com return fault; 27011308Santhony.gutierrez@amd.com } 27111308Santhony.gutierrez@amd.com 27211308Santhony.gutierrez@amd.com %(op_decl)s; 27311308Santhony.gutierrez@amd.com %(op_rd)s; 27411308Santhony.gutierrez@amd.com 27511308Santhony.gutierrez@amd.com getMem(pkt, Mem, traceData); 27611308Santhony.gutierrez@amd.com 27711308Santhony.gutierrez@amd.com if (fault == NoFault) { 27811308Santhony.gutierrez@amd.com %(memacc_code)s; 27911308Santhony.gutierrez@amd.com } 28011308Santhony.gutierrez@amd.com 28111308Santhony.gutierrez@amd.com if (fault == NoFault) { 28211308Santhony.gutierrez@amd.com %(op_wb)s; 28311308Santhony.gutierrez@amd.com } 28411308Santhony.gutierrez@amd.com 28511308Santhony.gutierrez@amd.com return fault; 28611308Santhony.gutierrez@amd.com } 28711308Santhony.gutierrez@amd.com}}; 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.comdef template StoreExecute {{ 29011308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 29111308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 29211308Santhony.gutierrez@amd.com { 29311308Santhony.gutierrez@amd.com Addr EA; 29411308Santhony.gutierrez@amd.com Fault fault = NoFault; 29511308Santhony.gutierrez@amd.com 29611308Santhony.gutierrez@amd.com %(fp_enable_check)s; 29711308Santhony.gutierrez@amd.com %(op_decl)s; 29811308Santhony.gutierrez@amd.com %(op_rd)s; 29911308Santhony.gutierrez@amd.com %(ea_code)s; 30011308Santhony.gutierrez@amd.com 30111308Santhony.gutierrez@amd.com if (fault == NoFault) { 30211308Santhony.gutierrez@amd.com %(memacc_code)s; 30311308Santhony.gutierrez@amd.com } 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.com if (fault == NoFault) { 30611308Santhony.gutierrez@amd.com fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 30711308Santhony.gutierrez@amd.com NULL); 30811308Santhony.gutierrez@amd.com } 30911308Santhony.gutierrez@amd.com 31011308Santhony.gutierrez@amd.com if (fault == NoFault) { 31111308Santhony.gutierrez@amd.com %(postacc_code)s; 31211308Santhony.gutierrez@amd.com } 31311308Santhony.gutierrez@amd.com 31411308Santhony.gutierrez@amd.com if (fault == NoFault) { 31511308Santhony.gutierrez@amd.com %(op_wb)s; 31611308Santhony.gutierrez@amd.com } 31711308Santhony.gutierrez@amd.com 31811308Santhony.gutierrez@amd.com return fault; 31911308Santhony.gutierrez@amd.com } 32011308Santhony.gutierrez@amd.com}}; 32111308Santhony.gutierrez@amd.com 32211308Santhony.gutierrez@amd.com 32311308Santhony.gutierrez@amd.comdef template StoreFPExecute {{ 32411308Santhony.gutierrez@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 32511308Santhony.gutierrez@amd.com Trace::InstRecord *traceData) const 32611308Santhony.gutierrez@amd.com { 327 Addr EA; 328 Fault fault = NoFault; 329 330 %(fp_enable_check)s; 331 if(fault != NoFault) 332 return fault; 333 %(op_decl)s; 334 %(op_rd)s; 335 %(ea_code)s; 336 337 if (fault == NoFault) { 338 %(memacc_code)s; 339 } 340 341 if (fault == NoFault) { 342 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 343 NULL); 344 } 345 346 if (fault == NoFault) { 347 %(postacc_code)s; 348 } 349 350 if (fault == NoFault) { 351 %(op_wb)s; 352 } 353 354 return fault; 355 } 356}}; 357 358def template StoreCondExecute {{ 359 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 360 Trace::InstRecord *traceData) const 361 { 362 Addr EA; 363 Fault fault = NoFault; 364 uint64_t write_result = 0; 365 366 %(fp_enable_check)s; 367 %(op_decl)s; 368 %(op_rd)s; 369 %(ea_code)s; 370 371 if (fault == NoFault) { 372 %(memacc_code)s; 373 } 374 375 if (fault == NoFault) { 376 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 377 &write_result); 378 } 379 380 if (fault == NoFault) { 381 %(postacc_code)s; 382 } 383 384 if (fault == NoFault) { 385 %(op_wb)s; 386 } 387 388 return fault; 389 } 390}}; 391 392def template StoreInitiateAcc {{ 393 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 394 Trace::InstRecord *traceData) const 395 { 396 Addr EA; 397 Fault fault = NoFault; 398 399 %(fp_enable_check)s; 400 %(op_decl)s; 401 %(op_rd)s; 402 %(ea_code)s; 403 404 if (fault == NoFault) { 405 %(memacc_code)s; 406 } 407 408 if (fault == NoFault) { 409 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 410 NULL); 411 } 412 413 return fault; 414 } 415}}; 416 417 418def template StoreCompleteAcc {{ 419 Fault %(class_name)s::completeAcc(Packet *pkt, 420 %(CPU_exec_context)s *xc, 421 Trace::InstRecord *traceData) const 422 { 423 return NoFault; 424 } 425}}; 426 427def template StoreCondCompleteAcc {{ 428 Fault %(class_name)s::completeAcc(Packet *pkt, 429 %(CPU_exec_context)s *xc, 430 Trace::InstRecord *traceData) const 431 { 432 Fault fault = NoFault; 433 434 %(fp_enable_check)s; 435 %(op_dest_decl)s; 436 437 uint64_t write_result = pkt->req->getExtraData(); 438 439 if (fault == NoFault) { 440 %(postacc_code)s; 441 } 442 443 if (fault == NoFault) { 444 %(op_wb)s; 445 } 446 447 return fault; 448 } 449}}; 450 451def template MiscExecute {{ 452 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 453 Trace::InstRecord *traceData) const 454 { 455 Addr EA M5_VAR_USED = 0; 456 Fault fault = NoFault; 457 458 %(fp_enable_check)s; 459 %(op_decl)s; 460 %(op_rd)s; 461 %(ea_code)s; 462 463 if (fault == NoFault) { 464 %(memacc_code)s; 465 } 466 467 return NoFault; 468 } 469}}; 470 471def template MiscInitiateAcc {{ 472 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 473 Trace::InstRecord *traceData) const 474 { 475 panic("Misc instruction does not support split access method!"); 476 return NoFault; 477 } 478}}; 479 480 481def template MiscCompleteAcc {{ 482 Fault %(class_name)s::completeAcc(Packet *pkt, 483 %(CPU_exec_context)s *xc, 484 Trace::InstRecord *traceData) const 485 { 486 panic("Misc instruction does not support split access method!"); 487 488 return NoFault; 489 } 490}}; 491 492def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 493 mem_flags = [], inst_flags = []) {{ 494 (header_output, decoder_output, decode_block, exec_output) = \ 495 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 496 decode_template = ImmNopCheckDecode, 497 exec_template_base = 'Load') 498}}; 499 500 501def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 502 mem_flags = [], inst_flags = []) {{ 503 (header_output, decoder_output, decode_block, exec_output) = \ 504 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 505 exec_template_base = 'Store') 506}}; 507 508def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 509 mem_flags = [], inst_flags = []) {{ 510 inst_flags += ['IsIndexed'] 511 (header_output, decoder_output, decode_block, exec_output) = \ 512 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 513 decode_template = ImmNopCheckDecode, 514 exec_template_base = 'Load') 515}}; 516 517def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 518 mem_flags = [], inst_flags = []) {{ 519 inst_flags += ['IsIndexed'] 520 (header_output, decoder_output, decode_block, exec_output) = \ 521 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 522 exec_template_base = 'Store') 523}}; 524 525def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 526 mem_flags = [], inst_flags = []) {{ 527 inst_flags += ['IsIndexed', 'IsFloating'] 528 (header_output, decoder_output, decode_block, exec_output) = \ 529 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 530 decode_template = ImmNopCheckDecode, 531 exec_template_base = 'Load') 532}}; 533 534def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 535 mem_flags = [], inst_flags = []) {{ 536 inst_flags += ['IsIndexed', 'IsFloating'] 537 (header_output, decoder_output, decode_block, exec_output) = \ 538 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 539 exec_template_base = 'Store') 540}}; 541 542 543def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 544 mem_flags = [], inst_flags = []) {{ 545 decl_code = 'uint32_t mem_word = Mem.uw;\n' 546 decl_code += 'uint32_t unalign_addr = Rs + disp;\n' 547 decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' 548 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 549 decl_code += '\tbyte_offset ^= 3;\n' 550 decl_code += '#endif\n' 551 552 memacc_code = decl_code + memacc_code 553 554 (header_output, decoder_output, decode_block, exec_output) = \ 555 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 556 decode_template = ImmNopCheckDecode, 557 exec_template_base = 'Load') 558}}; 559 560def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 561 mem_flags = [], inst_flags = []) {{ 562 decl_code = ''' 563 uint32_t mem_word = 0; 564 uint32_t unaligned_addr = Rs + disp; 565 uint32_t byte_offset = unaligned_addr & 3; 566 #if BYTE_ORDER == BIG_ENDIAN 567 byte_offset ^= 3; 568 #endif 569 fault = readMemAtomic(xc, traceData, EA, mem_word, memAccessFlags); 570 ''' 571 memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' 572 573 (header_output, decoder_output, decode_block, exec_output) = \ 574 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 575 exec_template_base = 'Store') 576}}; 577 578def format Prefetch(ea_code = {{ EA = Rs + disp; }}, 579 mem_flags = [], pf_flags = [], inst_flags = []) {{ 580 pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] 581 pf_inst_flags = inst_flags 582 583 (header_output, decoder_output, decode_block, exec_output) = \ 584 LoadStoreBase(name, Name, ea_code, 585 'warn_once("Prefetching not implemented for MIPS\\n");', 586 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 587 588}}; 589 590def format StoreCond(memacc_code, postacc_code, 591 ea_code = {{ EA = Rs + disp; }}, 592 mem_flags = [], inst_flags = []) {{ 593 (header_output, decoder_output, decode_block, exec_output) = \ 594 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 595 postacc_code, exec_template_base = 'StoreCond') 596}}; 597