merge
[gem5.git] / src / cpu / inorder / reg_dep_map.cc
1 /*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
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 * Authors: Korey Sewell
29 *
30 */
31
32 #include "arch/isa_traits.hh"
33 #include "cpu/inorder/pipeline_traits.hh"
34 #include "cpu/inorder/reg_dep_map.hh"
35 #include "cpu/inorder/inorder_dyn_inst.hh"
36 #include "cpu/inorder/cpu.hh"
37
38 using namespace std;
39 using namespace TheISA;
40 using namespace ThePipeline;
41
42 RegDepMap::RegDepMap(int size)
43 {
44 regMap.resize(size);
45 }
46
47 string
48 RegDepMap::name()
49 {
50 return cpu->name() + ".RegDepMap";
51 }
52
53 void
54 RegDepMap::setCPU(InOrderCPU *_cpu)
55 {
56 cpu = _cpu;
57 }
58
59 void
60 RegDepMap::clear()
61 {
62 regMap.clear();
63 }
64
65 void
66 RegDepMap::insert(DynInstPtr inst)
67 {
68 int dest_regs = inst->numDestRegs();
69
70 DPRINTF(RegDepMap, "Setting Output Dependencies for [sn:%i] "
71 ", %s (dest. regs = %i).\n",
72 inst->seqNum,
73 inst->staticInst->getName(),
74 dest_regs);
75
76 for (int i = 0; i < dest_regs; i++) {
77 int idx = inst->destRegIdx(i);
78
79 //if (inst->numFPDestRegs())
80 // idx += TheISA::FP_Base_DepTag;
81
82 insert(idx, inst);
83 }
84 }
85
86
87 void
88 RegDepMap::insert(unsigned idx, DynInstPtr inst)
89 {
90 DPRINTF(RegDepMap, "Inserting [sn:%i] onto dep. list for reg. idx %i.\n",
91 inst->seqNum, idx);
92
93 regMap[idx].push_back(inst);
94
95 inst->setRegDepEntry();
96 }
97
98 void
99 RegDepMap::remove(DynInstPtr inst)
100 {
101 if (inst->isRegDepEntry()) {
102 DPRINTF(RegDepMap, "Removing [sn:%i]'s entries from reg. dep. map.\n",
103 inst->seqNum);
104
105 int dest_regs = inst->numDestRegs();
106
107 for (int i = 0; i < dest_regs; i++) {
108 int idx = inst->destRegIdx(i);
109 remove(idx, inst);
110 }
111 }
112 }
113
114 void
115 RegDepMap::remove(unsigned idx, DynInstPtr inst)
116 {
117 std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
118 std::list<DynInstPtr>::iterator list_end = regMap[idx].end();
119
120 while (list_it != list_end) {
121 if((*list_it) == inst) {
122 regMap[idx].erase(list_it);
123 break;
124 }
125
126 list_it++;
127 }
128 }
129
130 void
131 RegDepMap::removeFront(unsigned idx, DynInstPtr inst)
132 {
133 std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
134
135 DPRINTF(RegDepMap, "[tid:%u]: Removing dependency entry on phys. reg."
136 "%i for [sn:%i].\n", inst->readTid(), idx, inst->seqNum);
137
138 assert(list_it != regMap[idx].end());
139
140 assert(inst == (*list_it));
141
142 regMap[idx].erase(list_it);
143 }
144
145 bool
146 RegDepMap::canRead(unsigned idx, DynInstPtr inst)
147 {
148 if (regMap[idx].size() == 0)
149 return true;
150
151 std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
152
153 if (inst->seqNum <= (*list_it)->seqNum) {
154 return true;
155 } else {
156 DPRINTF(RegDepMap, "[sn:%i] Can't read from RegFile, [sn:%i] has not written"
157 " it's value back yet.\n", inst->seqNum, (*list_it)->seqNum);
158 return false;
159 }
160 }
161
162 ThePipeline::DynInstPtr
163 RegDepMap::canForward(unsigned reg_idx, unsigned src_idx, DynInstPtr inst)
164 {
165 std::list<DynInstPtr>::iterator list_it = regMap[reg_idx].begin();
166 std::list<DynInstPtr>::iterator list_end = regMap[reg_idx].end();
167
168 DynInstPtr forward_inst = NULL;
169
170 // Look for first, oldest instruction
171 while (list_it != list_end &&
172 (*list_it)->seqNum < inst->seqNum) {
173 forward_inst = (*list_it);
174 list_it++;
175 }
176
177 if (forward_inst) {
178 if (forward_inst->isExecuted() &&
179 forward_inst->readResultTime(src_idx) < curTick) {
180 return forward_inst;
181 } else {
182 DPRINTF(RegDepMap, "[sn:%i] Can't get value through forwarding, "
183 " [sn:%i] has not been executed yet.\n",
184 inst->seqNum, forward_inst->seqNum);
185 return NULL;
186 }
187 } else {
188 DPRINTF(RegDepMap, "[sn:%i] No instruction found to forward from.\n",
189 inst->seqNum);
190 return NULL;
191 }
192 }
193
194 bool
195 RegDepMap::canWrite(unsigned idx, DynInstPtr inst)
196 {
197 if (regMap[idx].size() == 0)
198 return true;
199
200 std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
201
202 if (inst->seqNum <= (*list_it)->seqNum) {
203 return true;
204 } else {
205 DPRINTF(RegDepMap, "[sn:%i] Can't write from RegFile: [sn:%i] has not written"
206 " it's value back yet.\n", inst->seqNum, (*list_it)->seqNum);
207 }
208
209 return false;
210 }
211
212 int
213 RegDepMap::depSize(unsigned idx)
214 {
215 return regMap[idx].size();
216 }
217
218 ThePipeline::DynInstPtr
219 RegDepMap::findBypassInst(unsigned idx)
220 {
221 std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
222
223 if (depSize(idx) == 1)
224 return NULL;
225
226 list_it++;
227
228 while (list_it != regMap[idx].end()) {
229 if((*list_it)->isExecuted()) {
230 return *list_it;
231 break;
232 }
233 }
234
235 return NULL;
236 }