static_inst.hh revision 2
112837Sgabeblack@google.com/* 212837Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan 312837Sgabeblack@google.com * All rights reserved. 412837Sgabeblack@google.com * 512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412837Sgabeblack@google.com * this software without specific prior written permission. 1512837Sgabeblack@google.com * 1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712837Sgabeblack@google.com */ 2812837Sgabeblack@google.com 2912837Sgabeblack@google.com#ifndef __STATIC_INST_HH__ 3012837Sgabeblack@google.com#define __STATIC_INST_HH__ 3112837Sgabeblack@google.com 3212837Sgabeblack@google.com#include <bitset> 3312957Sgabeblack@google.com#include <string> 3412957Sgabeblack@google.com 3513053Sgabeblack@google.com#include "host.hh" 3612842Sgabeblack@google.com#include "hashmap.hh" 3712837Sgabeblack@google.com#include "refcnt.hh" 3812837Sgabeblack@google.com 3912957Sgabeblack@google.com#include "op_class.hh" 4012957Sgabeblack@google.com#include "isa_traits.hh" 4112957Sgabeblack@google.com 4212957Sgabeblack@google.com// forward declarations 4313091Sgabeblack@google.comclass ExecContext; 4412957Sgabeblack@google.comclass SpecExecContext; 4512957Sgabeblack@google.comclass SimpleCPU; 4612957Sgabeblack@google.comclass CPU; 4712957Sgabeblack@google.comclass DynInst; 4812837Sgabeblack@google.comclass SymbolTable; 4912837Sgabeblack@google.com 5012837Sgabeblack@google.comnamespace Trace { 5112837Sgabeblack@google.com class InstRecord; 5212837Sgabeblack@google.com} 5312837Sgabeblack@google.com 5412837Sgabeblack@google.com/** 5512837Sgabeblack@google.com * Base, ISA-independent static instruction class. 5612837Sgabeblack@google.com * 5712837Sgabeblack@google.com * The main component of this class is the vector of flags and the 5812837Sgabeblack@google.com * associated methods for reading them. Any object that can rely 5912837Sgabeblack@google.com * solely on these flags can process instructions without being 6012837Sgabeblack@google.com * recompiled for multiple ISAs. 6112837Sgabeblack@google.com */ 6212837Sgabeblack@google.comclass StaticInstBase : public RefCounted 6312957Sgabeblack@google.com{ 6412842Sgabeblack@google.com protected: 6512842Sgabeblack@google.com 6612938Sgabeblack@google.com /// Set of boolean static instruction properties. 6712957Sgabeblack@google.com /// 6812957Sgabeblack@google.com /// Notes: 6912957Sgabeblack@google.com /// - The IsInteger and IsFloating flags are based on the class of 7012938Sgabeblack@google.com /// registers accessed by the instruction. Although most 7112938Sgabeblack@google.com /// instructions will have exactly one of these two flags set, it 7212938Sgabeblack@google.com /// is possible for an instruction to have neither (e.g., direct 7312938Sgabeblack@google.com /// unconditional branches, memory barriers) or both (e.g., an 7412944Sgabeblack@google.com /// FP/int conversion). 7513091Sgabeblack@google.com /// - If IsMemRef is set, then exactly one of IsLoad or IsStore 7613091Sgabeblack@google.com /// will be set. Prefetches are marked as IsLoad, even if they 7712944Sgabeblack@google.com /// prefetch exclusive copies. 7812944Sgabeblack@google.com /// - If IsControl is set, then exactly one of IsDirectControl or 7912944Sgabeblack@google.com /// IsIndirect Control will be set, and exactly one of 8012957Sgabeblack@google.com /// IsCondControl or IsUncondControl will be set. 8113059Sgabeblack@google.com /// 8213059Sgabeblack@google.com enum Flags { 8313059Sgabeblack@google.com IsNop, ///< Is a no-op (no effect at all). 8413059Sgabeblack@google.com 8513059Sgabeblack@google.com IsInteger, ///< References integer regs. 8612957Sgabeblack@google.com IsFloating, ///< References FP regs. 8712957Sgabeblack@google.com 8813053Sgabeblack@google.com IsMemRef, ///< References memory (load, store, or prefetch). 8913053Sgabeblack@google.com IsLoad, ///< Reads from memory (load or prefetch). 9013053Sgabeblack@google.com IsStore, ///< Writes to memory. 9113053Sgabeblack@google.com IsInstPrefetch, ///< Instruction-cache prefetch. 9213053Sgabeblack@google.com IsDataPrefetch, ///< Data-cache prefetch. 9313053Sgabeblack@google.com 9412957Sgabeblack@google.com IsControl, ///< Control transfer instruction. 9512957Sgabeblack@google.com IsDirectControl, ///< PC relative control transfer. 9612957Sgabeblack@google.com IsIndirectControl, ///< Register indirect control transfer. 9713053Sgabeblack@google.com IsCondControl, ///< Conditional control transfer. 9813053Sgabeblack@google.com IsUncondControl, ///< Unconditional control transfer. 9912837Sgabeblack@google.com IsCall, ///< Subroutine call. 10012837Sgabeblack@google.com IsReturn, ///< Subroutine return. 10112837Sgabeblack@google.com 10212837Sgabeblack@google.com IsThreadSync, ///< Thread synchronization operation. 10312837Sgabeblack@google.com 10412837Sgabeblack@google.com NumFlags 10513053Sgabeblack@google.com }; 10613053Sgabeblack@google.com 10712837Sgabeblack@google.com /// Flag values for this instruction. 10813053Sgabeblack@google.com std::bitset<NumFlags> flags; 10913053Sgabeblack@google.com 11012837Sgabeblack@google.com /// See opClass(). 11113090Sgabeblack@google.com OpClass _opClass; 11213090Sgabeblack@google.com 11313090Sgabeblack@google.com /// See numSrcRegs(). 11413090Sgabeblack@google.com int8_t _numSrcRegs; 11513090Sgabeblack@google.com 11613090Sgabeblack@google.com /// See numDestRegs(). 11713090Sgabeblack@google.com int8_t _numDestRegs; 11813090Sgabeblack@google.com 11913090Sgabeblack@google.com /// The following are used to track physical register usage 12013090Sgabeblack@google.com /// for machines with separate int & FP reg files. 12113090Sgabeblack@google.com //@{ 12213090Sgabeblack@google.com int8_t _numFPDestRegs; 12312837Sgabeblack@google.com int8_t _numIntDestRegs; 12413090Sgabeblack@google.com //@} 12513090Sgabeblack@google.com 12613090Sgabeblack@google.com /// Constructor. 12713090Sgabeblack@google.com /// It's important to initialize everything here to a sane 12813090Sgabeblack@google.com /// default, since the decoder generally only overrides 12913090Sgabeblack@google.com /// the fields that are meaningful for the particular 13013090Sgabeblack@google.com /// instruction. 13113090Sgabeblack@google.com StaticInstBase(OpClass __opClass) 13213090Sgabeblack@google.com : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0), 13313090Sgabeblack@google.com _numFPDestRegs(0), _numIntDestRegs(0) 13413090Sgabeblack@google.com { 13513090Sgabeblack@google.com } 13612837Sgabeblack@google.com 13713090Sgabeblack@google.com public: 13813090Sgabeblack@google.com 13913090Sgabeblack@google.com /// @name Register information. 14013090Sgabeblack@google.com /// The sum of numFPDestRegs() and numIntDestRegs() equals 14113090Sgabeblack@google.com /// numDestRegs(). The former two functions are used to track 14213090Sgabeblack@google.com /// physical register usage for machines with separate int & FP 14313090Sgabeblack@google.com /// reg files. 14413090Sgabeblack@google.com //@{ 14513090Sgabeblack@google.com /// Number of source registers. 14613090Sgabeblack@google.com int8_t numSrcRegs() const { return _numSrcRegs; } 14713090Sgabeblack@google.com /// Number of destination registers. 14813090Sgabeblack@google.com int8_t numDestRegs() const { return _numDestRegs; } 14912837Sgabeblack@google.com /// Number of floating-point destination regs. 15012837Sgabeblack@google.com int8_t numFPDestRegs() const { return _numFPDestRegs; } 15113059Sgabeblack@google.com /// Number of integer destination regs. 15213059Sgabeblack@google.com int8_t numIntDestRegs() const { return _numIntDestRegs; } 15313059Sgabeblack@google.com //@} 15413059Sgabeblack@google.com 15512837Sgabeblack@google.com /// @name Flag accessors. 15612842Sgabeblack@google.com /// These functions are used to access the values of the various 15713036Sgabeblack@google.com /// instruction property flags. See StaticInstBase::Flags for descriptions 15812842Sgabeblack@google.com /// of the individual flags. 15912842Sgabeblack@google.com //@{ 16012842Sgabeblack@google.com 16112842Sgabeblack@google.com bool isNop() const { return flags[IsNop]; } 16212842Sgabeblack@google.com 16312837Sgabeblack@google.com bool isMemRef() const { return flags[IsMemRef]; } 16412944Sgabeblack@google.com bool isLoad() const { return flags[IsLoad]; } 16512944Sgabeblack@google.com bool isStore() const { return flags[IsStore]; } 16613053Sgabeblack@google.com bool isInstPrefetch() const { return flags[IsInstPrefetch]; } 16712944Sgabeblack@google.com bool isDataPrefetch() const { return flags[IsDataPrefetch]; } 16813053Sgabeblack@google.com 16913053Sgabeblack@google.com bool isInteger() const { return flags[IsInteger]; } 17013053Sgabeblack@google.com bool isFloating() const { return flags[IsFloating]; } 17113053Sgabeblack@google.com 17212944Sgabeblack@google.com bool isControl() const { return flags[IsControl]; } 17312944Sgabeblack@google.com bool isCall() const { return flags[IsCall]; } 17412944Sgabeblack@google.com bool isReturn() const { return flags[IsReturn]; } 17513053Sgabeblack@google.com bool isDirectCtrl() const { return flags[IsDirectControl]; } 17612944Sgabeblack@google.com bool isIndirectCtrl() const { return flags[IsIndirectControl]; } 17713053Sgabeblack@google.com bool isCondCtrl() const { return flags[IsCondControl]; } 17813053Sgabeblack@google.com bool isUncondCtrl() const { return flags[IsUncondControl]; } 17913053Sgabeblack@google.com 18013053Sgabeblack@google.com bool isThreadSync() const { return flags[IsThreadSync]; } 18112944Sgabeblack@google.com //@} 18212944Sgabeblack@google.com 18312944Sgabeblack@google.com /// Operation class. Used to select appropriate function unit in issue. 18412837Sgabeblack@google.com OpClass opClass() const { return _opClass; } 18513053Sgabeblack@google.com}; 18613053Sgabeblack@google.com 18713090Sgabeblack@google.com 18813090Sgabeblack@google.com// forward declaration 18913090Sgabeblack@google.comtemplate <class ISA> 19013090Sgabeblack@google.comclass StaticInstPtr; 19113090Sgabeblack@google.com 19213090Sgabeblack@google.com/** 19313053Sgabeblack@google.com * Generic yet ISA-dependent static instruction class. 19413053Sgabeblack@google.com * 19513053Sgabeblack@google.com * This class builds on StaticInstBase, defining fields and interfaces 19613053Sgabeblack@google.com * that are generic across all ISAs but that differ in details 19713053Sgabeblack@google.com * according to the specific ISA being used. 19813053Sgabeblack@google.com */ 19913053Sgabeblack@google.comtemplate <class ISA> 20013053Sgabeblack@google.comclass StaticInst : public StaticInstBase 20112837Sgabeblack@google.com{ 20212837Sgabeblack@google.com public: 20312837Sgabeblack@google.com 20412837Sgabeblack@google.com /// Binary machine instruction type. 20512837Sgabeblack@google.com typedef typename ISA::MachInst MachInst; 20612837Sgabeblack@google.com /// Memory address type. 20712837Sgabeblack@google.com typedef typename ISA::Addr Addr; 20812837Sgabeblack@google.com /// Logical register index type. 20912837Sgabeblack@google.com typedef typename ISA::RegIndex RegIndex; 21012837Sgabeblack@google.com 21112868Sgabeblack@google.com enum { 21212842Sgabeblack@google.com MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs 21312842Sgabeblack@google.com MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs 21412837Sgabeblack@google.com }; 21512868Sgabeblack@google.com 21612868Sgabeblack@google.com 21712868Sgabeblack@google.com /// Return logical index (architectural reg num) of i'th destination reg. 21812868Sgabeblack@google.com /// Only the entries from 0 through numDestRegs()-1 are valid. 21912868Sgabeblack@google.com RegIndex destRegIdx(int i) { return _destRegIdx[i]; } 22012868Sgabeblack@google.com 22112868Sgabeblack@google.com /// Return logical index (architectural reg num) of i'th source reg. 22212868Sgabeblack@google.com /// Only the entries from 0 through numSrcRegs()-1 are valid. 22312868Sgabeblack@google.com RegIndex srcRegIdx(int i) { return _srcRegIdx[i]; } 22412868Sgabeblack@google.com 22512868Sgabeblack@google.com /// Pointer to a statically allocated "null" instruction object. 22612868Sgabeblack@google.com /// Used to give eaCompInst() and memAccInst() something to return 22712868Sgabeblack@google.com /// when called on non-memory instructions. 22812868Sgabeblack@google.com static StaticInstPtr<ISA> nullStaticInstPtr; 22912868Sgabeblack@google.com 23012868Sgabeblack@google.com /** 23112868Sgabeblack@google.com * Memory references only: returns "fake" instruction representing 23212868Sgabeblack@google.com * the effective address part of the memory operation. Used to 23312868Sgabeblack@google.com * obtain the dependence info (numSrcRegs and srcRegIdx[]) for 23412868Sgabeblack@google.com * just the EA computation. 23512868Sgabeblack@google.com */ 23612868Sgabeblack@google.com virtual StaticInstPtr<ISA> eaCompInst() { return nullStaticInstPtr; } 23712868Sgabeblack@google.com 23812868Sgabeblack@google.com /** 23912868Sgabeblack@google.com * Memory references only: returns "fake" instruction representing 24012868Sgabeblack@google.com * the memory access part of the memory operation. Used to 24112868Sgabeblack@google.com * obtain the dependence info (numSrcRegs and srcRegIdx[]) for 24212868Sgabeblack@google.com * just the memory access (not the EA computation). 24312868Sgabeblack@google.com */ 24412868Sgabeblack@google.com virtual StaticInstPtr<ISA> memAccInst() { return nullStaticInstPtr; } 24512868Sgabeblack@google.com 24612868Sgabeblack@google.com /// The binary machine instruction. 24712868Sgabeblack@google.com const MachInst machInst; 24812868Sgabeblack@google.com 24912868Sgabeblack@google.com protected: 25012868Sgabeblack@google.com 25112868Sgabeblack@google.com /// See destRegIdx(). 25212868Sgabeblack@google.com RegIndex _destRegIdx[MaxInstDestRegs]; 25312868Sgabeblack@google.com /// See srcRegIdx(). 25412868Sgabeblack@google.com RegIndex _srcRegIdx[MaxInstSrcRegs]; 25512842Sgabeblack@google.com 25612837Sgabeblack@google.com /** 25712837Sgabeblack@google.com * Base mnemonic (e.g., "add"). Used by generateDisassembly() 25812837Sgabeblack@google.com * methods. Also useful to readily identify instructions from 25912837Sgabeblack@google.com * within the debugger when #cachedDisassembly has not been 26012837Sgabeblack@google.com * initialized. 26112837Sgabeblack@google.com */ 26212837Sgabeblack@google.com const char *mnemonic; 26312837Sgabeblack@google.com 26412837Sgabeblack@google.com /** 26512837Sgabeblack@google.com * String representation of disassembly (lazily evaluated via 266 * disassemble()). 267 */ 268 std::string *cachedDisassembly; 269 270 /** 271 * Internal function to generate disassembly string. 272 */ 273 virtual std::string generateDisassembly(Addr pc, 274 const SymbolTable *symtab) = 0; 275 276 /// Constructor. 277 StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass) 278 : StaticInstBase(__opClass), 279 machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0) 280 { 281 } 282 283 public: 284 285 virtual ~StaticInst() 286 { 287 if (cachedDisassembly) 288 delete cachedDisassembly; 289 } 290 291 /** 292 * Execute this instruction under SimpleCPU model. 293 */ 294 virtual Fault execute(SimpleCPU *cpu, ExecContext *xc, 295 Trace::InstRecord *traceData) = 0; 296 297 /** 298 * Execute this instruction under detailed CPU model. 299 */ 300 virtual Fault execute(CPU *cpu, SpecExecContext *xc, DynInst *dynInst, 301 Trace::InstRecord *traceData) = 0; 302 303 /** 304 * Return the target address for a PC-relative branch. 305 * Invalid if not a PC-relative branch (i.e. isDirectCtrl() 306 * should be true). 307 */ 308 virtual Addr branchTarget(Addr branchPC) 309 { 310 panic("StaticInst::branchTarget() called on instruction " 311 "that is not a PC-relative branch."); 312 } 313 314 /** 315 * Return the target address for an indirect branch (jump). 316 * The register value is read from the supplied execution context. 317 * Invalid if not an indirect branch (i.e. isIndirectCtrl() 318 * should be true). 319 */ 320 virtual Addr branchTarget(ExecContext *xc) 321 { 322 panic("StaticInst::branchTarget() called on instruction " 323 "that is not an indirect branch."); 324 } 325 326 /** 327 * Return true if the instruction is a control transfer, and if so, 328 * return the target address as well. 329 */ 330 bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt); 331 332 /** 333 * Return string representation of disassembled instruction. 334 * The default version of this function will call the internal 335 * virtual generateDisassembly() function to get the string, 336 * then cache it in #cachedDisassembly. If the disassembly 337 * should not be cached, this function should be overridden directly. 338 */ 339 virtual const std::string &disassemble(Addr pc, 340 const SymbolTable *symtab = 0) 341 { 342 if (!cachedDisassembly) 343 cachedDisassembly = 344 new std::string(generateDisassembly(pc, symtab)); 345 346 return *cachedDisassembly; 347 } 348 349 /// Decoded instruction cache type. 350 /// For now we're using a generic hash_map; this seems to work 351 /// pretty well. 352 typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache; 353 354 /// A cache of decoded instruction objects. 355 static DecodeCache decodeCache; 356 357 /** 358 * Dump some basic stats on the decode cache hash map. 359 * Only gets called if DECODE_CACHE_HASH_STATS is defined. 360 */ 361 static void dumpDecodeCacheStats(); 362 363 /// Decode a machine instruction. 364 /// @param mach_inst The binary instruction to decode. 365 /// @retval A pointer to the corresponding StaticInst object. 366 static 367 StaticInstPtr<ISA> decode(MachInst mach_inst) 368 { 369#ifdef DECODE_CACHE_HASH_STATS 370 // Simple stats on decode hash_map. Turns out the default 371 // hash function is as good as anything I could come up with. 372 const int dump_every_n = 10000000; 373 static int decodes_til_dump = dump_every_n; 374 375 if (--decodes_til_dump == 0) { 376 dumpDecodeCacheStats(); 377 decodes_til_dump = dump_every_n; 378 } 379#endif 380 381 typename DecodeCache::iterator iter = decodeCache.find(mach_inst); 382 if (iter != decodeCache.end()) { 383 return iter->second; 384 } 385 386 StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst); 387 decodeCache[mach_inst] = si; 388 return si; 389 } 390}; 391 392typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr; 393 394/// Reference-counted pointer to a StaticInst object. 395/// This type should be used instead of "StaticInst<ISA> *" so that 396/// StaticInst objects can be properly reference-counted. 397template <class ISA> 398class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> > 399{ 400 public: 401 /// Constructor. 402 StaticInstPtr() 403 : RefCountingPtr<StaticInst<ISA> >() 404 { 405 } 406 407 /// Conversion from "StaticInst<ISA> *". 408 StaticInstPtr(StaticInst<ISA> *p) 409 : RefCountingPtr<StaticInst<ISA> >(p) 410 { 411 } 412 413 /// Copy constructor. 414 StaticInstPtr(const StaticInstPtr &r) 415 : RefCountingPtr<StaticInst<ISA> >(r) 416 { 417 } 418 419 /// Construct directly from machine instruction. 420 /// Calls StaticInst<ISA>::decode(). 421 StaticInstPtr(typename ISA::MachInst mach_inst) 422 : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst)) 423 { 424 } 425 426 /// Convert to pointer to StaticInstBase class. 427 operator const StaticInstBasePtr() 428 { 429 return get(); 430 } 431}; 432 433#endif // __STATIC_INST_HH__ 434