gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scoreboard.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Andrew Bardsley
38  */
39 
40 #include "cpu/minor/scoreboard.hh"
41 
42 #include "arch/registers.hh"
43 #include "cpu/reg_class.hh"
44 #include "debug/MinorScoreboard.hh"
45 #include "debug/MinorTiming.hh"
46 
47 namespace Minor
48 {
49 
50 bool
52 {
53  RegClass reg_class = regIdxToClass(reg);
54  bool ret = false;
55 
56  if (reg == TheISA::ZeroReg) {
57  /* Don't bother with the zero register */
58  ret = false;
59  } else {
60  switch (reg_class)
61  {
62  case IntRegClass:
63  scoreboard_index = reg;
64  ret = true;
65  break;
66  case FloatRegClass:
67  scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
68  reg - TheISA::FP_Reg_Base;
69  ret = true;
70  break;
71  case CCRegClass:
72  scoreboard_index = TheISA::NumIntRegs + reg - TheISA::FP_Reg_Base;
73  ret = true;
74  break;
75  case MiscRegClass:
76  /* Don't bother with Misc registers */
77  ret = false;
78  break;
79  }
80  }
81 
82  return ret;
83 }
84 
86 static TheISA::RegIndex
88 {
89  RegClass reg_class = regIdxToClass(reg);
90  TheISA::RegIndex ret = reg;
91 
92  switch (reg_class)
93  {
94  case IntRegClass:
95  ret = thread_context->flattenIntIndex(reg);
96  break;
97  case FloatRegClass:
98  ret = thread_context->flattenFloatIndex(reg);
99  break;
100  case CCRegClass:
101  ret = thread_context->flattenCCIndex(reg);
102  break;
103  case MiscRegClass:
104  /* Don't bother to flatten misc regs as we don't need them here */
105  /* return thread_context->flattenMiscIndex(reg); */
106  ret = reg;
107  break;
108  }
109 
110  return ret;
111 }
112 
113 void
115  ThreadContext *thread_context, bool mark_unpredictable)
116 {
117  if (inst->isFault())
118  return;
119 
120  StaticInstPtr staticInst = inst->staticInst;
121  unsigned int num_dests = staticInst->numDestRegs();
122 
124  for (unsigned int dest_index = 0; dest_index < num_dests;
125  dest_index++)
126  {
128  staticInst->destRegIdx(dest_index), thread_context);
129  Index index;
130 
131  if (findIndex(reg, index)) {
132  if (mark_unpredictable)
134 
135  inst->flatDestRegIdx[dest_index] = reg;
136 
137  numResults[index]++;
138  returnCycle[index] = retire_time;
139  /* We should be able to rely on only being given accending
140  * execSeqNums, but sanity check */
141  if (inst->id.execSeqNum > writingInst[index]) {
142  writingInst[index] = inst->id.execSeqNum;
143  fuIndices[index] = inst->fuIndex;
144  }
145 
146  DPRINTF(MinorScoreboard, "Marking up inst: %s"
147  " regIndex: %d final numResults: %d returnCycle: %d\n",
148  *inst, index, numResults[index], returnCycle[index]);
149  } else {
150  /* Use ZeroReg to mark invalid/untracked dests */
151  inst->flatDestRegIdx[dest_index] = TheISA::ZeroReg;
152  }
153  }
154 }
155 
158  ThreadContext *thread_context)
159 {
160  InstSeqNum ret = 0;
161 
162  if (inst->isFault())
163  return ret;
164 
165  StaticInstPtr staticInst = inst->staticInst;
166  unsigned int num_srcs = staticInst->numSrcRegs();
167 
168  for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
169  RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
170  thread_context);
171  unsigned short int index;
172 
173  if (findIndex(reg, index)) {
174  if (writingInst[index] > ret)
175  ret = writingInst[index];
176  }
177  }
178 
179  DPRINTF(MinorScoreboard, "Inst: %s depends on execSeqNum: %d\n",
180  *inst, ret);
181 
182  return ret;
183 }
184 
185 void
186 Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
187 {
188  if (inst->isFault())
189  return;
190 
191  StaticInstPtr staticInst = inst->staticInst;
192  unsigned int num_dests = staticInst->numDestRegs();
193 
195  for (unsigned int dest_index = 0; dest_index < num_dests;
196  dest_index++)
197  {
198  RegIndex reg = inst->flatDestRegIdx[dest_index];
199  Index index;
200 
201  if (findIndex(reg, index)) {
202  if (clear_unpredictable && numUnpredictableResults[index] != 0)
204 
205  numResults[index] --;
206 
207  if (numResults[index] == 0) {
208  returnCycle[index] = Cycles(0);
209  writingInst[index] = 0;
210  fuIndices[index] = -1;
211  }
212 
213  DPRINTF(MinorScoreboard, "Clearing inst: %s"
214  " regIndex: %d final numResults: %d\n",
215  *inst, index, numResults[index]);
216  }
217  }
218 }
219 
220 bool
222  const std::vector<Cycles> *src_reg_relative_latencies,
223  const std::vector<bool> *cant_forward_from_fu_indices,
224  Cycles now, ThreadContext *thread_context)
225 {
226  /* Always allow fault to be issued */
227  if (inst->isFault())
228  return true;
229 
230  StaticInstPtr staticInst = inst->staticInst;
231  unsigned int num_srcs = staticInst->numSrcRegs();
232 
233  /* Default to saying you can issue */
234  bool ret = true;
235 
236  unsigned int num_relative_latencies = 0;
237  Cycles default_relative_latency = Cycles(0);
238 
239  /* Where relative latencies are given, the default is the last
240  * one as that allows the rel. lat. list to be shorted than the
241  * number of src. regs */
242  if (src_reg_relative_latencies &&
243  src_reg_relative_latencies->size() != 0)
244  {
245  num_relative_latencies = src_reg_relative_latencies->size();
246  default_relative_latency = (*src_reg_relative_latencies)
247  [num_relative_latencies-1];
248  }
249 
250  /* For each source register, find the latest result */
251  unsigned int src_index = 0;
252  while (src_index < num_srcs && /* More registers */
253  ret /* Still possible */)
254  {
255  RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
256  thread_context);
257  unsigned short int index;
258 
259  if (findIndex(reg, index)) {
260  bool cant_forward = fuIndices[index] != 1 &&
261  cant_forward_from_fu_indices &&
262  index < cant_forward_from_fu_indices->size() &&
263  (*cant_forward_from_fu_indices)[index];
264 
265  Cycles relative_latency = (cant_forward ? Cycles(0) :
266  (src_index >= num_relative_latencies ?
267  default_relative_latency :
268  (*src_reg_relative_latencies)[src_index]));
269 
270  if (returnCycle[index] > (now + relative_latency) ||
272  {
273  ret = false;
274  }
275  }
276  src_index++;
277  }
278 
279  if (DTRACE(MinorTiming)) {
280  if (ret && num_srcs > num_relative_latencies &&
281  num_relative_latencies != 0)
282  {
283  DPRINTF(MinorTiming, "Warning, inst: %s timing extra decode has"
284  " more src. regs: %d than relative latencies: %d\n",
285  staticInst->disassemble(0), num_srcs, num_relative_latencies);
286  }
287  }
288 
289  return ret;
290 }
291 
292 void
294 {
295  std::ostringstream result_stream;
296 
297  bool printed_element = false;
298 
299  unsigned int i = 0;
300  while (i < numRegs) {
301  unsigned short int num_results = numResults[i];
302  unsigned short int num_unpredictable_results =
304 
305  if (!(num_results == 0 && num_unpredictable_results == Cycles(0))) {
306  if (printed_element)
307  result_stream << ',';
308 
309  result_stream << '(' << i << ','
310  << num_results << '/'
311  << num_unpredictable_results << '/'
312  << returnCycle[i] << '/'
313  << writingInst[i] << ')';
314 
315  printed_element = true;
316  }
317 
318  i++;
319  }
320 
321  MINORTRACE("busy=%s\n", result_stream.str());
322 }
323 
324 }
std::vector< Index > numUnpredictableResults
Count of the number of results which can't be predicted.
Definition: scoreboard.hh:81
#define DPRINTF(x,...)
Definition: trace.hh:212
Bitfield< 30, 0 > index
Bitfield< 5, 3 > reg
Definition: types.hh:89
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Floating-point register.
Definition: reg_class.hh:43
Bitfield< 7 > i
Definition: miscregs.hh:1378
Control (misc) register.
Definition: reg_class.hh:45
virtual const std::string & disassemble(Addr pc, const SymbolTable *symtab=0) const
Return string representation of disassembled instruction.
Definition: static_inst.cc:89
unsigned short int Index
Type to use when indexing numResults.
Definition: scoreboard.hh:74
RegClass
Enumerate the classes of registers.
Definition: reg_class.hh:41
RegIndex destRegIdx(int i) const
Return logical index (architectural reg num) of i'th destination reg.
Definition: static_inst.hh:188
ThreadContext is the external interface to all thread state for anything outside of the CPU...
virtual int flattenFloatIndex(int reg)=0
static TheISA::RegIndex flattenRegIndex(TheISA::RegIndex reg, ThreadContext *thread_context)
Flatten a RegIndex, irrespective of what reg type it's pointing to.
Definition: scoreboard.cc:87
void minorTrace() const
MinorTraceIF interface.
Definition: scoreboard.cc:293
std::vector< int > fuIndices
Index of the FU generating this result.
Definition: scoreboard.hh:84
std::vector< InstSeqNum > writingInst
The execute sequence number of the most recent inst to generate this register value.
Definition: scoreboard.hh:94
uint8_t RegIndex
Definition: registers.hh:46
void clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
Clear down the dependencies for this instruction.
Definition: scoreboard.cc:186
#define DTRACE(x)
Definition: trace.hh:210
const int NumCCRegs
Definition: registers.hh:97
void markupInstDests(MinorDynInstPtr inst, Cycles retire_time, ThreadContext *thread_context, bool mark_unpredictable)
Mark up an instruction's effects by incrementing numResults counts.
Definition: scoreboard.cc:114
const RegIndex ZeroReg
Definition: registers.hh:77
Condition-code register.
Definition: reg_class.hh:44
A simple instruction scoreboard for tracking dependencies in Execute.
uint64_t InstSeqNum
Definition: inst_seq.hh:40
bool canInstIssue(MinorDynInstPtr inst, const std::vector< Cycles > *src_reg_relative_latencies, const std::vector< bool > *cant_forward_from_fu_indices, Cycles now, ThreadContext *thread_context)
Can this instruction be issued.
Definition: scoreboard.cc:221
InstSeqNum execSeqNumToWaitFor(MinorDynInstPtr inst, ThreadContext *thread_context)
Returns the exec sequence number of the most recent inst on which the given inst depends.
Definition: scoreboard.cc:157
virtual int flattenIntIndex(int reg)=0
RegIndex srcRegIdx(int i) const
Return logical index (architectural reg num) of i'th source reg.
Definition: static_inst.hh:192
int8_t numSrcRegs() const
Number of source registers.
Definition: static_inst.hh:112
virtual int flattenCCIndex(int reg)=0
std::vector< Index > numResults
Count of the number of in-flight instructions that have results for each register.
Definition: scoreboard.hh:78
bool findIndex(RegIndex reg, Index &scoreboard_index)
Sets scoreboard_index to the index into numResults of the given register index.
Definition: scoreboard.cc:51
#define MINORTRACE(...)
DPRINTFN for MinorTrace reporting.
Definition: trace.hh:62
TheISA::RegIndex RegIndex
Type to use for thread context registers.
Definition: scoreboard.hh:71
Integer register.
Definition: reg_class.hh:42
RegClass regIdxToClass(TheISA::RegIndex reg_idx, TheISA::RegIndex *rel_reg_idx=NULL)
Map a 'unified' architectural register index to its register class.
Definition: reg_class.hh:66
std::vector< Cycles > returnCycle
The estimated cycle number that the result will be presented.
Definition: scoreboard.hh:90
const unsigned numRegs
The number of registers in the Scoreboard.
Definition: scoreboard.hh:68
const int NumIntRegs
Definition: registers.hh:95
int8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:114

Generated on Fri Jun 9 2017 13:03:42 for gem5 by doxygen 1.8.6