2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef __CPU_STATIC_INST_HH__
30 #define __CPU_STATIC_INST_HH__
35 #include "base/hashmap.hh"
36 #include "base/misc.hh"
37 #include "base/refcnt.hh"
38 #include "cpu/op_class.hh"
39 #include "sim/host.hh"
40 #include "arch/isa_traits.hh"
42 // forward declarations
43 struct AlphaSimpleImpl;
52 class AtomicSimpleCPU;
53 class TimingSimpleCPU;
62 * Base, ISA-independent static instruction class.
64 * The main component of this class is the vector of flags and the
65 * associated methods for reading them. Any object that can rely
66 * solely on these flags can process instructions without being
67 * recompiled for multiple ISAs.
69 class StaticInstBase : public RefCounted
73 /// Set of boolean static instruction properties.
76 /// - The IsInteger and IsFloating flags are based on the class of
77 /// registers accessed by the instruction. Although most
78 /// instructions will have exactly one of these two flags set, it
79 /// is possible for an instruction to have neither (e.g., direct
80 /// unconditional branches, memory barriers) or both (e.g., an
81 /// FP/int conversion).
82 /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
84 /// - If IsControl is set, then exactly one of IsDirectControl or
85 /// IsIndirect Control will be set, and exactly one of
86 /// IsCondControl or IsUncondControl will be set.
87 /// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
88 /// implemented as flags since in the current model there's no
89 /// other way for instructions to inject behavior into the
90 /// pipeline outside of fetch. Once we go to an exec-in-exec CPU
91 /// model we should be able to get rid of these flags and
92 /// implement this behavior via the execute() methods.
95 IsNop, ///< Is a no-op (no effect at all).
97 IsInteger, ///< References integer regs.
98 IsFloating, ///< References FP regs.
100 IsMemRef, ///< References memory (load, store, or prefetch).
101 IsLoad, ///< Reads from memory (load or prefetch).
102 IsStore, ///< Writes to memory.
103 IsInstPrefetch, ///< Instruction-cache prefetch.
104 IsDataPrefetch, ///< Data-cache prefetch.
105 IsCopy, ///< Fast Cache block copy
107 IsControl, ///< Control transfer instruction.
108 IsDirectControl, ///< PC relative control transfer.
109 IsIndirectControl, ///< Register indirect control transfer.
110 IsCondControl, ///< Conditional control transfer.
111 IsUncondControl, ///< Unconditional control transfer.
112 IsCall, ///< Subroutine call.
113 IsReturn, ///< Subroutine return.
115 IsCondDelaySlot,///< Conditional Delay-Slot Instruction
117 IsThreadSync, ///< Thread synchronization operation.
119 IsSerializing, ///< Serializes pipeline: won't execute until all
120 /// older instructions have committed.
123 IsMemBarrier, ///< Is a memory barrier
124 IsWriteBarrier, ///< Is a write barrier
126 IsNonSpeculative, ///< Should not be executed speculatively
131 /// Flag values for this instruction.
132 std::bitset<NumFlags> flags;
137 /// See numSrcRegs().
140 /// See numDestRegs().
143 /// The following are used to track physical register usage
144 /// for machines with separate int & FP reg files.
146 int8_t _numFPDestRegs;
147 int8_t _numIntDestRegs;
151 /// It's important to initialize everything here to a sane
152 /// default, since the decoder generally only overrides
153 /// the fields that are meaningful for the particular
155 StaticInstBase(OpClass __opClass)
156 : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
157 _numFPDestRegs(0), _numIntDestRegs(0)
163 /// @name Register information.
164 /// The sum of numFPDestRegs() and numIntDestRegs() equals
165 /// numDestRegs(). The former two functions are used to track
166 /// physical register usage for machines with separate int & FP
169 /// Number of source registers.
170 int8_t numSrcRegs() const { return _numSrcRegs; }
171 /// Number of destination registers.
172 int8_t numDestRegs() const { return _numDestRegs; }
173 /// Number of floating-point destination regs.
174 int8_t numFPDestRegs() const { return _numFPDestRegs; }
175 /// Number of integer destination regs.
176 int8_t numIntDestRegs() const { return _numIntDestRegs; }
179 /// @name Flag accessors.
180 /// These functions are used to access the values of the various
181 /// instruction property flags. See StaticInstBase::Flags for descriptions
182 /// of the individual flags.
185 bool isNop() const { return flags[IsNop]; }
187 bool isMemRef() const { return flags[IsMemRef]; }
188 bool isLoad() const { return flags[IsLoad]; }
189 bool isStore() const { return flags[IsStore]; }
190 bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
191 bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
192 bool isCopy() const { return flags[IsCopy];}
194 bool isInteger() const { return flags[IsInteger]; }
195 bool isFloating() const { return flags[IsFloating]; }
197 bool isControl() const { return flags[IsControl]; }
198 bool isCall() const { return flags[IsCall]; }
199 bool isReturn() const { return flags[IsReturn]; }
200 bool isDirectCtrl() const { return flags[IsDirectControl]; }
201 bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
202 bool isCondCtrl() const { return flags[IsCondControl]; }
203 bool isUncondCtrl() const { return flags[IsUncondControl]; }
205 bool isThreadSync() const { return flags[IsThreadSync]; }
206 bool isSerializing() const { return flags[IsSerializing] ||
207 flags[IsSerializeBefore] ||
208 flags[IsSerializeAfter]; }
209 bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
210 bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
211 bool isMemBarrier() const { return flags[IsMemBarrier]; }
212 bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
213 bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
216 /// Operation class. Used to select appropriate function unit in issue.
217 OpClass opClass() const { return _opClass; }
221 // forward declaration
225 * Generic yet ISA-dependent static instruction class.
227 * This class builds on StaticInstBase, defining fields and interfaces
228 * that are generic across all ISAs but that differ in details
229 * according to the specific ISA being used.
231 class StaticInst : public StaticInstBase
235 /// Binary machine instruction type.
236 typedef TheISA::MachInst MachInst;
237 /// Binary extended machine instruction type.
238 typedef TheISA::ExtMachInst ExtMachInst;
239 /// Logical register index type.
240 typedef TheISA::RegIndex RegIndex;
243 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
244 MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
248 /// Return logical index (architectural reg num) of i'th destination reg.
249 /// Only the entries from 0 through numDestRegs()-1 are valid.
250 RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
252 /// Return logical index (architectural reg num) of i'th source reg.
253 /// Only the entries from 0 through numSrcRegs()-1 are valid.
254 RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
256 /// Pointer to a statically allocated "null" instruction object.
257 /// Used to give eaCompInst() and memAccInst() something to return
258 /// when called on non-memory instructions.
259 static StaticInstPtr nullStaticInstPtr;
262 * Memory references only: returns "fake" instruction representing
263 * the effective address part of the memory operation. Used to
264 * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
265 * just the EA computation.
268 StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; }
271 * Memory references only: returns "fake" instruction representing
272 * the memory access part of the memory operation. Used to
273 * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
274 * just the memory access (not the EA computation).
277 StaticInstPtr &memAccInst() const { return nullStaticInstPtr; }
279 /// The binary machine instruction.
280 const ExtMachInst machInst;
284 /// See destRegIdx().
285 RegIndex _destRegIdx[MaxInstDestRegs];
287 RegIndex _srcRegIdx[MaxInstSrcRegs];
290 * Base mnemonic (e.g., "add"). Used by generateDisassembly()
291 * methods. Also useful to readily identify instructions from
292 * within the debugger when #cachedDisassembly has not been
295 const char *mnemonic;
298 * String representation of disassembly (lazily evaluated via
301 mutable std::string *cachedDisassembly;
304 * Internal function to generate disassembly string.
307 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
310 StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
311 : StaticInstBase(__opClass),
312 machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
318 virtual ~StaticInst()
320 if (cachedDisassembly)
321 delete cachedDisassembly;
325 * The execute() signatures are auto-generated by scons based on the
326 * set of CPU models we are compiling in today.
328 #include "cpu/static_inst_exec_sigs.hh"
331 * Return the target address for a PC-relative branch.
332 * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
335 virtual Addr branchTarget(Addr branchPC) const
337 panic("StaticInst::branchTarget() called on instruction "
338 "that is not a PC-relative branch.");
342 * Return the target address for an indirect branch (jump). The
343 * register value is read from the supplied execution context, so
344 * the result is valid only if the execution context is about to
345 * execute the branch in question. Invalid if not an indirect
346 * branch (i.e. isIndirectCtrl() should be true).
348 virtual Addr branchTarget(ExecContext *xc) const
350 panic("StaticInst::branchTarget() called on instruction "
351 "that is not an indirect branch.");
355 * Return true if the instruction is a control transfer, and if so,
356 * return the target address as well.
358 bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const;
361 * Return string representation of disassembled instruction.
362 * The default version of this function will call the internal
363 * virtual generateDisassembly() function to get the string,
364 * then cache it in #cachedDisassembly. If the disassembly
365 * should not be cached, this function should be overridden directly.
367 virtual const std::string &disassemble(Addr pc,
368 const SymbolTable *symtab = 0) const
370 if (!cachedDisassembly)
372 new std::string(generateDisassembly(pc, symtab));
374 return *cachedDisassembly;
377 /// Decoded instruction cache type.
378 /// For now we're using a generic hash_map; this seems to work
380 typedef m5::hash_map<ExtMachInst, StaticInstPtr> DecodeCache;
382 /// A cache of decoded instruction objects.
383 static DecodeCache decodeCache;
386 * Dump some basic stats on the decode cache hash map.
387 * Only gets called if DECODE_CACHE_HASH_STATS is defined.
389 static void dumpDecodeCacheStats();
391 /// Decode a machine instruction.
392 /// @param mach_inst The binary instruction to decode.
393 /// @retval A pointer to the corresponding StaticInst object.
394 //This is defined as inline below.
395 static StaticInstPtr decode(ExtMachInst mach_inst);
397 //MIPS Decoder Debug Functions
398 int getOpcode() { return (machInst & 0xFC000000) >> 26 ; }//31..26
399 int getRs() { return (machInst & 0x03E00000) >> 21; } //25...21
400 int getRt() { return (machInst & 0x001F0000) >> 16; } //20...16
401 int getRd() { return (machInst & 0x0000F800) >> 11; } //15...11
402 int getImm() { return (machInst & 0x0000FFFF); } //15...0
403 int getFunction(){ return (machInst & 0x0000003F); }//5...0
404 int getBranch(){ return (machInst & 0x0000FFFF); }//15...0
405 int getJump(){ return (machInst & 0x03FFFFFF); }//5...0
406 int getHint(){ return (machInst & 0x000007C0) >> 6; } //10...6
407 std::string getName() { return mnemonic; }
410 typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
412 /// Reference-counted pointer to a StaticInst object.
413 /// This type should be used instead of "StaticInst *" so that
414 /// StaticInst objects can be properly reference-counted.
415 class StaticInstPtr : public RefCountingPtr<StaticInst>
420 : RefCountingPtr<StaticInst>()
424 /// Conversion from "StaticInst *".
425 StaticInstPtr(StaticInst *p)
426 : RefCountingPtr<StaticInst>(p)
430 /// Copy constructor.
431 StaticInstPtr(const StaticInstPtr &r)
432 : RefCountingPtr<StaticInst>(r)
436 /// Construct directly from machine instruction.
437 /// Calls StaticInst::decode().
438 StaticInstPtr(TheISA::ExtMachInst mach_inst)
439 : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
443 /// Convert to pointer to StaticInstBase class.
444 operator const StaticInstBasePtr()
451 StaticInst::decode(StaticInst::ExtMachInst mach_inst)
453 #ifdef DECODE_CACHE_HASH_STATS
454 // Simple stats on decode hash_map. Turns out the default
455 // hash function is as good as anything I could come up with.
456 const int dump_every_n = 10000000;
457 static int decodes_til_dump = dump_every_n;
459 if (--decodes_til_dump == 0) {
460 dumpDecodeCacheStats();
461 decodes_til_dump = dump_every_n;
465 DecodeCache::iterator iter = decodeCache.find(mach_inst);
466 if (iter != decodeCache.end()) {
470 StaticInstPtr si = TheISA::decodeInst(mach_inst);
471 decodeCache[mach_inst] = si;
475 #endif // __CPU_STATIC_INST_HH__