2 * Copyright (c) 2007 MIPS Technologies, Inc.
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.
28 * Authors: Korey Sewell
32 #include "arch/isa_traits.hh"
33 #include "config/the_isa.hh"
34 #include "cpu/inorder/cpu.hh"
35 #include "cpu/inorder/inorder_dyn_inst.hh"
36 #include "cpu/inorder/pipeline_traits.hh"
37 #include "cpu/inorder/reg_dep_map.hh"
38 #include "debug/RegDepMap.hh"
41 using namespace TheISA
;
42 using namespace ThePipeline
;
44 RegDepMap::RegDepMap(int size
)
46 regMap
.resize(InOrderCPU::NumRegTypes
);
47 regMap
[InOrderCPU::IntType
].resize(NumIntRegs
);
48 regMap
[InOrderCPU::FloatType
].resize(NumFloatRegs
);
49 regMap
[InOrderCPU::MiscType
].resize(NumMiscRegs
);
52 RegDepMap::~RegDepMap()
60 return cpu
->name() + ".RegDepMap";
63 std::string
RegDepMap::mapNames
[InOrderCPU::NumRegTypes
] =
64 {"IntReg", "FloatReg", "MiscReg"};
67 RegDepMap::setCPU(InOrderCPU
*_cpu
)
76 for (int i
= 0; i
< regMap
.size(); i
++) {
77 for (int j
= 0; j
< regMap
[j
].size(); j
++)
85 RegDepMap::insert(DynInstPtr inst
)
87 int dest_regs
= inst
->numDestRegs();
89 DPRINTF(RegDepMap
, "Setting Output Dependencies for [sn:%i] "
90 ", %s (dest. regs = %i).\n",
95 for (int i
= 0; i
< dest_regs
; i
++) {
96 InOrderCPU::RegType reg_type
;
97 TheISA::RegIndex raw_idx
= inst
->destRegIdx(i
);
98 TheISA::RegIndex flat_idx
= cpu
->flattenRegIdx(raw_idx
,
102 DPRINTF(RegDepMap
, "[sn:%i] #%i flattened %i to %i.\n",
103 inst
->seqNum
, i
, raw_idx
, flat_idx
);
105 inst
->flattenDestReg(i
, flat_idx
);
107 if (flat_idx
== TheISA::ZeroReg
&& reg_type
== InOrderCPU::IntType
) {
108 DPRINTF(RegDepMap
, "[sn:%i]: Ignoring Insert-Dependency tracking for "
109 "ISA-ZeroReg (Int. Reg %i).\n", inst
->seqNum
,
114 insert(reg_type
, flat_idx
, inst
);
120 RegDepMap::insert(uint8_t reg_type
, RegIndex idx
, DynInstPtr inst
)
122 DPRINTF(RegDepMap
, "Inserting [sn:%i] onto %s dep. list for "
123 "reg. idx %i.\n", inst
->seqNum
, mapNames
[reg_type
],
126 regMap
[reg_type
][idx
].push_back(inst
);
128 inst
->setRegDepEntry();
132 RegDepMap::remove(DynInstPtr inst
)
134 if (inst
->isRegDepEntry()) {
135 int dest_regs
= inst
->numDestRegs();
137 DPRINTF(RegDepMap
, "Removing [sn:%i]'s entries from reg. dep. map. for "
138 ", %s (dest. regs = %i).\n",
144 for (int i
= 0; i
< dest_regs
; i
++) {
145 RegIndex flat_idx
= inst
->flattenedDestRegIdx(i
);
146 InOrderCPU::RegType reg_type
= cpu
->getRegType(inst
->destRegIdx(i
));
148 // Merge Dyn Inst & CPU Result Types
149 if (flat_idx
== TheISA::ZeroReg
&&
150 reg_type
== InOrderCPU::IntType
) {
151 DPRINTF(RegDepMap
, "[sn:%i]: Ignoring Remove-Dependency tracking for "
152 "ISA-ZeroReg (Int. Reg %i).\n", inst
->seqNum
,
158 remove(reg_type
, flat_idx
, inst
);
161 inst
->clearRegDepEntry();
166 RegDepMap::remove(uint8_t reg_type
, RegIndex idx
, DynInstPtr inst
)
168 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_type
][idx
].begin();
169 std::list
<DynInstPtr
>::iterator list_end
= regMap
[reg_type
][idx
].end();
172 while (list_it
!= list_end
) {
173 if((*list_it
) == inst
) {
174 DPRINTF(RegDepMap
, "Removing [sn:%i] from %s dep. list for "
175 "reg. idx %i.\n", inst
->seqNum
, mapNames
[reg_type
],
177 regMap
[reg_type
][idx
].erase(list_it
);
182 panic("[sn:%i] Did not find entry for %i, type:%i\n", inst
->seqNum
, idx
, reg_type
);
186 RegDepMap::removeFront(uint8_t reg_type
, RegIndex idx
, DynInstPtr inst
)
188 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_type
][idx
].begin();
190 DPRINTF(RegDepMap
, "[tid:%u]: Removing dependency entry on reg. idx "
191 "%i for [sn:%i].\n", inst
->readTid(), idx
, inst
->seqNum
);
193 assert(list_it
!= regMap
[reg_type
][idx
].end());
195 assert(inst
== (*list_it
));
197 regMap
[reg_type
][idx
].erase(list_it
);
201 RegDepMap::canRead(uint8_t reg_type
, RegIndex idx
, DynInstPtr inst
)
203 if (regMap
[reg_type
][idx
].size() == 0)
206 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_type
][idx
].begin();
208 if (inst
->seqNum
<= (*list_it
)->seqNum
) {
211 DPRINTF(RegDepMap
, "[sn:%i] Can't read from RegFile, [sn:%i] has "
212 "not written it's value back yet.\n",
213 inst
->seqNum
, (*list_it
)->seqNum
);
218 ThePipeline::DynInstPtr
219 RegDepMap::canForward(uint8_t reg_type
, unsigned reg_idx
, DynInstPtr inst
)
221 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_type
][reg_idx
].begin();
222 std::list
<DynInstPtr
>::iterator list_end
= regMap
[reg_type
][reg_idx
].end();
224 DynInstPtr forward_inst
= NULL
;
226 // Look for instruction immediately in front of requestor to supply
228 while (list_it
!= list_end
&&
229 (*list_it
)->seqNum
< inst
->seqNum
) {
230 forward_inst
= (*list_it
);
235 int dest_reg_idx
= forward_inst
->getDestIdxNum(reg_idx
);
236 assert(dest_reg_idx
!= -1);
238 DPRINTF(RegDepMap
, "[sn:%i] Found potential forwarding value for reg %i "
239 " w/ [sn:%i] dest. reg. #%i\n",
240 inst
->seqNum
, reg_idx
, forward_inst
->seqNum
, dest_reg_idx
);
242 if (forward_inst
->isExecuted() &&
243 forward_inst
->readResultTime(dest_reg_idx
) < curTick()) {
246 if (!forward_inst
->isExecuted()) {
247 DPRINTF(RegDepMap
, "[sn:%i] Can't get value through "
248 "forwarding, [sn:%i] %s has not been executed yet.\n",
249 inst
->seqNum
, forward_inst
->seqNum
, forward_inst
->instName());
250 } else if (forward_inst
->readResultTime(dest_reg_idx
) >= curTick()) {
251 DPRINTF(RegDepMap
, "[sn:%i] Can't get value through "
252 "forwarding, [sn:%i] executed on tick:%i.\n",
253 inst
->seqNum
, forward_inst
->seqNum
,
254 forward_inst
->readResultTime(dest_reg_idx
));
260 DPRINTF(RegDepMap
, "[sn:%i] No instruction found to forward from.\n",
267 RegDepMap::canWrite(uint8_t reg_type
, RegIndex idx
, DynInstPtr inst
)
269 if (regMap
[reg_type
][idx
].size() == 0)
272 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_type
][idx
].begin();
274 if (inst
->seqNum
<= (*list_it
)->seqNum
) {
277 DPRINTF(RegDepMap
, "[sn:%i] Can't write from RegFile: [sn:%i] "
278 "has not written it's value back yet.\n", inst
->seqNum
,
288 for (int reg_type
= 0; reg_type
< InOrderCPU::NumRegTypes
; reg_type
++) {
289 for (int idx
=0; idx
< regMap
.size(); idx
++) {
290 if (regMap
[idx
].size() > 0) {
291 cprintf("Reg #%i (size:%i): ", idx
, regMap
[reg_type
][idx
].size());
293 std::list
<DynInstPtr
>::iterator list_it
=
294 regMap
[reg_type
][idx
].begin();
295 std::list
<DynInstPtr
>::iterator list_end
=
296 regMap
[reg_type
][idx
].end();
298 while (list_it
!= list_end
) {
299 cprintf("[sn:%i] ", (*list_it
)->seqNum
);