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 "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"
39 using namespace TheISA
;
40 using namespace ThePipeline
;
42 RegDepMap::RegDepMap(int size
)
50 return cpu
->name() + ".RegDepMap";
54 RegDepMap::setCPU(InOrderCPU
*_cpu
)
66 RegDepMap::insert(DynInstPtr inst
)
68 int dest_regs
= inst
->numDestRegs();
70 DPRINTF(RegDepMap
, "Setting Output Dependencies for [sn:%i] "
71 ", %s (dest. regs = %i).\n",
73 inst
->staticInst
->getName(),
76 for (int i
= 0; i
< dest_regs
; i
++) {
77 int idx
= inst
->destRegIdx(i
);
79 //if (inst->numFPDestRegs())
80 // idx += TheISA::FP_Base_DepTag;
88 RegDepMap::insert(unsigned idx
, DynInstPtr inst
)
90 DPRINTF(RegDepMap
, "Inserting [sn:%i] onto dep. list for reg. idx %i.\n",
93 regMap
[idx
].push_back(inst
);
95 inst
->setRegDepEntry();
99 RegDepMap::remove(DynInstPtr inst
)
101 if (inst
->isRegDepEntry()) {
102 DPRINTF(RegDepMap
, "Removing [sn:%i]'s entries from reg. dep. map.\n",
105 int dest_regs
= inst
->numDestRegs();
107 for (int i
= 0; i
< dest_regs
; i
++) {
108 int idx
= inst
->destRegIdx(i
);
115 RegDepMap::remove(unsigned idx
, DynInstPtr inst
)
117 std::list
<DynInstPtr
>::iterator list_it
= regMap
[idx
].begin();
118 std::list
<DynInstPtr
>::iterator list_end
= regMap
[idx
].end();
120 while (list_it
!= list_end
) {
121 if((*list_it
) == inst
) {
122 regMap
[idx
].erase(list_it
);
131 RegDepMap::removeFront(unsigned idx
, DynInstPtr inst
)
133 std::list
<DynInstPtr
>::iterator list_it
= regMap
[idx
].begin();
135 DPRINTF(RegDepMap
, "[tid:%u]: Removing dependency entry on phys. reg."
136 "%i for [sn:%i].\n", inst
->readTid(), idx
, inst
->seqNum
);
138 assert(list_it
!= regMap
[idx
].end());
140 assert(inst
== (*list_it
));
142 regMap
[idx
].erase(list_it
);
146 RegDepMap::canRead(unsigned idx
, DynInstPtr inst
)
148 if (regMap
[idx
].size() == 0)
151 std::list
<DynInstPtr
>::iterator list_it
= regMap
[idx
].begin();
153 if (inst
->seqNum
<= (*list_it
)->seqNum
) {
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
);
162 ThePipeline::DynInstPtr
163 RegDepMap::canForward(unsigned reg_idx
, unsigned src_idx
, DynInstPtr inst
)
165 std::list
<DynInstPtr
>::iterator list_it
= regMap
[reg_idx
].begin();
166 std::list
<DynInstPtr
>::iterator list_end
= regMap
[reg_idx
].end();
168 DynInstPtr forward_inst
= NULL
;
170 // Look for first, oldest instruction
171 while (list_it
!= list_end
&&
172 (*list_it
)->seqNum
< inst
->seqNum
) {
173 forward_inst
= (*list_it
);
178 if (forward_inst
->isExecuted() &&
179 forward_inst
->readResultTime(src_idx
) < curTick
) {
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
);
188 DPRINTF(RegDepMap
, "[sn:%i] No instruction found to forward from.\n",
195 RegDepMap::canWrite(unsigned idx
, DynInstPtr inst
)
197 if (regMap
[idx
].size() == 0)
200 std::list
<DynInstPtr
>::iterator list_it
= regMap
[idx
].begin();
202 if (inst
->seqNum
<= (*list_it
)->seqNum
) {
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
);
213 RegDepMap::depSize(unsigned idx
)
215 return regMap
[idx
].size();
218 ThePipeline::DynInstPtr
219 RegDepMap::findBypassInst(unsigned idx
)
221 std::list
<DynInstPtr
>::iterator list_it
= regMap
[idx
].begin();
223 if (depSize(idx
) == 1)
228 while (list_it
!= regMap
[idx
].end()) {
229 if((*list_it
)->isExecuted()) {