New directory structure:
[gem5.git] / src / cpu / static_inst.hh
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 */
28
29 #ifndef __CPU_STATIC_INST_HH__
30 #define __CPU_STATIC_INST_HH__
31
32 #include <bitset>
33 #include <string>
34
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"
41
42 // forward declarations
43 struct AlphaSimpleImpl;
44 class ExecContext;
45 class DynInst;
46 class Packet;
47
48 template <class Impl>
49 class AlphaDynInst;
50
51 class FastCPU;
52 class AtomicSimpleCPU;
53 class TimingSimpleCPU;
54 class InorderCPU;
55 class SymbolTable;
56
57 namespace Trace {
58 class InstRecord;
59 }
60
61 /**
62 * Base, ISA-independent static instruction class.
63 *
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.
68 */
69 class StaticInstBase : public RefCounted
70 {
71 protected:
72
73 /// Set of boolean static instruction properties.
74 ///
75 /// Notes:
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
83 /// will be set.
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.
93 ///
94 enum Flags {
95 IsNop, ///< Is a no-op (no effect at all).
96
97 IsInteger, ///< References integer regs.
98 IsFloating, ///< References FP regs.
99
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
106
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.
114
115 IsCondDelaySlot,///< Conditional Delay-Slot Instruction
116
117 IsThreadSync, ///< Thread synchronization operation.
118
119 IsSerializing, ///< Serializes pipeline: won't execute until all
120 /// older instructions have committed.
121 IsSerializeBefore,
122 IsSerializeAfter,
123 IsMemBarrier, ///< Is a memory barrier
124 IsWriteBarrier, ///< Is a write barrier
125
126 IsNonSpeculative, ///< Should not be executed speculatively
127
128 NumFlags
129 };
130
131 /// Flag values for this instruction.
132 std::bitset<NumFlags> flags;
133
134 /// See opClass().
135 OpClass _opClass;
136
137 /// See numSrcRegs().
138 int8_t _numSrcRegs;
139
140 /// See numDestRegs().
141 int8_t _numDestRegs;
142
143 /// The following are used to track physical register usage
144 /// for machines with separate int & FP reg files.
145 //@{
146 int8_t _numFPDestRegs;
147 int8_t _numIntDestRegs;
148 //@}
149
150 /// Constructor.
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
154 /// instruction.
155 StaticInstBase(OpClass __opClass)
156 : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
157 _numFPDestRegs(0), _numIntDestRegs(0)
158 {
159 }
160
161 public:
162
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
167 /// reg files.
168 //@{
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; }
177 //@}
178
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.
183 //@{
184
185 bool isNop() const { return flags[IsNop]; }
186
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];}
193
194 bool isInteger() const { return flags[IsInteger]; }
195 bool isFloating() const { return flags[IsFloating]; }
196
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]; }
204
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]; }
214 //@}
215
216 /// Operation class. Used to select appropriate function unit in issue.
217 OpClass opClass() const { return _opClass; }
218 };
219
220
221 // forward declaration
222 class StaticInstPtr;
223
224 /**
225 * Generic yet ISA-dependent static instruction class.
226 *
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.
230 */
231 class StaticInst : public StaticInstBase
232 {
233 public:
234
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;
241
242 enum {
243 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
244 MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
245 };
246
247
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]; }
251
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]; }
255
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;
260
261 /**
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.
266 */
267 virtual const
268 StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; }
269
270 /**
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).
275 */
276 virtual const
277 StaticInstPtr &memAccInst() const { return nullStaticInstPtr; }
278
279 /// The binary machine instruction.
280 const ExtMachInst machInst;
281
282 protected:
283
284 /// See destRegIdx().
285 RegIndex _destRegIdx[MaxInstDestRegs];
286 /// See srcRegIdx().
287 RegIndex _srcRegIdx[MaxInstSrcRegs];
288
289 /**
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
293 * initialized.
294 */
295 const char *mnemonic;
296
297 /**
298 * String representation of disassembly (lazily evaluated via
299 * disassemble()).
300 */
301 mutable std::string *cachedDisassembly;
302
303 /**
304 * Internal function to generate disassembly string.
305 */
306 virtual std::string
307 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
308
309 /// Constructor.
310 StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
311 : StaticInstBase(__opClass),
312 machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
313 {
314 }
315
316 public:
317
318 virtual ~StaticInst()
319 {
320 if (cachedDisassembly)
321 delete cachedDisassembly;
322 }
323
324 /**
325 * The execute() signatures are auto-generated by scons based on the
326 * set of CPU models we are compiling in today.
327 */
328 #include "cpu/static_inst_exec_sigs.hh"
329
330 /**
331 * Return the target address for a PC-relative branch.
332 * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
333 * should be true).
334 */
335 virtual Addr branchTarget(Addr branchPC) const
336 {
337 panic("StaticInst::branchTarget() called on instruction "
338 "that is not a PC-relative branch.");
339 }
340
341 /**
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).
347 */
348 virtual Addr branchTarget(ExecContext *xc) const
349 {
350 panic("StaticInst::branchTarget() called on instruction "
351 "that is not an indirect branch.");
352 }
353
354 /**
355 * Return true if the instruction is a control transfer, and if so,
356 * return the target address as well.
357 */
358 bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const;
359
360 /**
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.
366 */
367 virtual const std::string &disassemble(Addr pc,
368 const SymbolTable *symtab = 0) const
369 {
370 if (!cachedDisassembly)
371 cachedDisassembly =
372 new std::string(generateDisassembly(pc, symtab));
373
374 return *cachedDisassembly;
375 }
376
377 /// Decoded instruction cache type.
378 /// For now we're using a generic hash_map; this seems to work
379 /// pretty well.
380 typedef m5::hash_map<ExtMachInst, StaticInstPtr> DecodeCache;
381
382 /// A cache of decoded instruction objects.
383 static DecodeCache decodeCache;
384
385 /**
386 * Dump some basic stats on the decode cache hash map.
387 * Only gets called if DECODE_CACHE_HASH_STATS is defined.
388 */
389 static void dumpDecodeCacheStats();
390
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);
396
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; }
408 };
409
410 typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
411
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>
416 {
417 public:
418 /// Constructor.
419 StaticInstPtr()
420 : RefCountingPtr<StaticInst>()
421 {
422 }
423
424 /// Conversion from "StaticInst *".
425 StaticInstPtr(StaticInst *p)
426 : RefCountingPtr<StaticInst>(p)
427 {
428 }
429
430 /// Copy constructor.
431 StaticInstPtr(const StaticInstPtr &r)
432 : RefCountingPtr<StaticInst>(r)
433 {
434 }
435
436 /// Construct directly from machine instruction.
437 /// Calls StaticInst::decode().
438 StaticInstPtr(TheISA::ExtMachInst mach_inst)
439 : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
440 {
441 }
442
443 /// Convert to pointer to StaticInstBase class.
444 operator const StaticInstBasePtr()
445 {
446 return this->get();
447 }
448 };
449
450 inline StaticInstPtr
451 StaticInst::decode(StaticInst::ExtMachInst mach_inst)
452 {
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;
458
459 if (--decodes_til_dump == 0) {
460 dumpDecodeCacheStats();
461 decodes_til_dump = dump_every_n;
462 }
463 #endif
464
465 DecodeCache::iterator iter = decodeCache.find(mach_inst);
466 if (iter != decodeCache.end()) {
467 return iter->second;
468 }
469
470 StaticInstPtr si = TheISA::decodeInst(mach_inst);
471 decodeCache[mach_inst] = si;
472 return si;
473 }
474
475 #endif // __CPU_STATIC_INST_HH__