2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
29 #include "cpu/o3/decode.hh"
32 SimpleDecode<Impl>::SimpleDecode(Params ¶ms)
33 : renameToDecodeDelay(params.renameToDecodeDelay),
34 iewToDecodeDelay(params.iewToDecodeDelay),
35 commitToDecodeDelay(params.commitToDecodeDelay),
36 fetchToDecodeDelay(params.fetchToDecodeDelay),
37 decodeWidth(params.decodeWidth),
40 DPRINTF(Decode, "Decode: decodeWidth=%i.\n", decodeWidth);
46 SimpleDecode<Impl>::regStats()
49 .name(name() + ".decodeIdleCycles")
50 .desc("Number of cycles decode is idle")
51 .prereq(decodeIdleCycles);
53 .name(name() + ".decodeBlockedCycles")
54 .desc("Number of cycles decode is blocked")
55 .prereq(decodeBlockedCycles);
57 .name(name() + ".decodeUnblockCycles")
58 .desc("Number of cycles decode is unblocking")
59 .prereq(decodeUnblockCycles);
61 .name(name() + ".decodeSquashCycles")
62 .desc("Number of cycles decode is squashing")
63 .prereq(decodeSquashCycles);
65 .name(name() + ".decodeBranchMispred")
66 .desc("Number of times decode detected a branch misprediction")
67 .prereq(decodeBranchMispred);
69 .name(name() + ".decodeControlMispred")
70 .desc("Number of times decode detected an instruction incorrectly"
71 " predicted as a control")
72 .prereq(decodeControlMispred);
74 .name(name() + ".decodeDecodedInsts")
75 .desc("Number of instructions handled by decode")
76 .prereq(decodeDecodedInsts);
78 .name(name() + ".decodeSquashedInsts")
79 .desc("Number of squashed instructions handled by decode")
80 .prereq(decodeSquashedInsts);
85 SimpleDecode<Impl>::setCPU(FullCPU *cpu_ptr)
87 DPRINTF(Decode, "Decode: Setting CPU pointer.\n");
93 SimpleDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
95 DPRINTF(Decode, "Decode: Setting time buffer pointer.\n");
98 // Setup wire to write information back to fetch.
99 toFetch = timeBuffer->getWire(0);
101 // Create wires to get information from proper places in time buffer.
102 fromRename = timeBuffer->getWire(-renameToDecodeDelay);
103 fromIEW = timeBuffer->getWire(-iewToDecodeDelay);
104 fromCommit = timeBuffer->getWire(-commitToDecodeDelay);
109 SimpleDecode<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
111 DPRINTF(Decode, "Decode: Setting decode queue pointer.\n");
112 decodeQueue = dq_ptr;
114 // Setup wire to write information to proper place in decode queue.
115 toRename = decodeQueue->getWire(0);
120 SimpleDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
122 DPRINTF(Decode, "Decode: Setting fetch queue pointer.\n");
125 // Setup wire to read information from fetch queue.
126 fromFetch = fetchQueue->getWire(-fetchToDecodeDelay);
131 SimpleDecode<Impl>::fetchInstsValid()
133 return fromFetch->size > 0;
138 SimpleDecode<Impl>::block()
140 DPRINTF(Decode, "Decode: Blocking.\n");
142 // Set the status to Blocked.
145 // Add the current inputs to the skid buffer so they can be
146 // reprocessed when this stage unblocks.
147 skidBuffer.push(*fromFetch);
149 // Note that this stage only signals previous stages to stall when
150 // it is the cause of the stall originates at this stage. Otherwise
151 // the previous stages are expected to check all possible stall signals.
156 SimpleDecode<Impl>::unblock()
158 DPRINTF(Decode, "Decode: Unblocking, going to remove "
159 "instructions from skid buffer.\n");
160 // Remove the now processed instructions from the skid buffer.
163 // If there's still information in the skid buffer, then
164 // continue to tell previous stages to stall. They will be
165 // able to restart once the skid buffer is empty.
166 if (!skidBuffer.empty()) {
167 toFetch->decodeInfo.stall = true;
169 DPRINTF(Decode, "Decode: Finished unblocking.\n");
174 // This squash is specifically for when Decode detects a PC-relative branch
175 // was predicted incorrectly.
178 SimpleDecode<Impl>::squash(DynInstPtr &inst)
180 DPRINTF(Decode, "Decode: Squashing due to incorrect branch prediction "
181 "detected at decode.\n");
182 Addr new_PC = inst->readNextPC();
184 toFetch->decodeInfo.branchMispredict = true;
185 toFetch->decodeInfo.doneSeqNum = inst->seqNum;
186 toFetch->decodeInfo.predIncorrect = true;
187 toFetch->decodeInfo.squash = true;
188 toFetch->decodeInfo.nextPC = new_PC;
189 toFetch->decodeInfo.branchTaken = true;
191 // Set status to squashing.
194 // Clear the skid buffer in case it has any data in it.
195 while (!skidBuffer.empty()) {
199 // Squash instructions up until this one
200 // Slightly unrealistic!
201 cpu->removeInstsUntil(inst->seqNum);
206 SimpleDecode<Impl>::squash()
208 DPRINTF(Decode, "Decode: Squashing.\n");
209 // Set status to squashing.
212 // Maybe advance the time buffer? Not sure what to do in the normal
215 // Clear the skid buffer in case it has any data in it.
216 while (!skidBuffer.empty())
224 SimpleDecode<Impl>::tick()
226 // Decode should try to execute as many instructions as its bandwidth
227 // will allow, as long as it is not currently blocked.
228 if (_status != Blocked && _status != Squashing) {
229 DPRINTF(Decode, "Decode: Not blocked, so attempting to run "
231 // Make sure that the skid buffer has something in it if the
232 // status is unblocking.
233 assert(_status == Unblocking ? !skidBuffer.empty() : 1);
237 // If the status was unblocking, then instructions from the skid
238 // buffer were used. Remove those instructions and handle
239 // the rest of unblocking.
240 if (_status == Unblocking) {
241 ++decodeUnblockCycles;
243 if (fetchInstsValid()) {
244 // Add the current inputs to the skid buffer so they can be
245 // reprocessed when this stage unblocks.
246 skidBuffer.push(*fromFetch);
251 } else if (_status == Blocked) {
252 ++decodeBlockedCycles;
254 if (fetchInstsValid()) {
258 if (!fromRename->renameInfo.stall &&
259 !fromIEW->iewInfo.stall &&
260 !fromCommit->commitInfo.stall) {
261 DPRINTF(Decode, "Decode: Stall signals cleared, going to "
263 _status = Unblocking;
265 // Continue to tell previous stage to block until this
266 // stage is done unblocking.
267 toFetch->decodeInfo.stall = true;
269 DPRINTF(Decode, "Decode: Still blocked.\n");
270 toFetch->decodeInfo.stall = true;
273 if (fromCommit->commitInfo.squash ||
274 fromCommit->commitInfo.robSquashing) {
277 } else if (_status == Squashing) {
278 if (!fromCommit->commitInfo.squash &&
279 !fromCommit->commitInfo.robSquashing) {
281 } else if (fromCommit->commitInfo.squash) {
282 ++decodeSquashCycles;
291 SimpleDecode<Impl>::decode()
293 // Check time buffer if being told to squash.
294 if (fromCommit->commitInfo.squash) {
299 // Check time buffer if being told to stall.
300 if (fromRename->renameInfo.stall ||
301 fromIEW->iewInfo.stall ||
302 fromCommit->commitInfo.stall) {
307 // Check fetch queue to see if instructions are available.
308 // If no available instructions, do nothing, unless this stage is
309 // currently unblocking.
310 if (!fetchInstsValid() && _status != Unblocking) {
311 DPRINTF(Decode, "Decode: Nothing to do, breaking out early.\n");
312 // Should I change the status to idle?
317 // Might be better to use a base DynInst * instead?
320 unsigned to_rename_index = 0;
322 int insts_available = _status == Unblocking ?
323 skidBuffer.front().size - numInst :
328 if (insts_available) {
329 DPRINTF(Decode, "Decode: Instructions available.\n");
331 if (_status == Unblocking && skidBuffer.empty()) {
332 DPRINTF(Decode, "Decode: No instructions available, skid buffer "
334 } else if (_status != Unblocking &&
335 !fromFetch->insts[0]) {
336 DPRINTF(Decode, "Decode: No instructions available, fetch queue "
339 panic("Decode: No instructions available, unexpected condition!"
345 while (insts_available > 0)
347 DPRINTF(Decode, "Decode: Sending instruction to rename.\n");
349 inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
350 fromFetch->insts[numInst];
352 DPRINTF(Decode, "Decode: Processing instruction %i with PC %#x\n",
353 inst->seqNum, inst->readPC());
355 if (inst->isSquashed()) {
356 DPRINTF(Decode, "Decode: Instruction %i with PC %#x is "
357 "squashed, skipping.\n",
358 inst->seqNum, inst->readPC());
360 ++decodeSquashedInsts;
369 // Also check if instructions have no source registers. Mark
370 // them as ready to issue at any time. Not sure if this check
371 // should exist here or at a later stage; however it doesn't matter
372 // too much for function correctness.
373 // Isn't this handled by the inst queue?
374 if (inst->numSrcRegs() == 0) {
378 // This current instruction is valid, so add it into the decode
379 // queue. The next instruction may not be valid, so check to
380 // see if branches were predicted correctly.
381 toRename->insts[to_rename_index] = inst;
385 // Ensure that if it was predicted as a branch, it really is a
387 if (inst->predTaken() && !inst->isControl()) {
388 panic("Instruction predicted as a branch!");
390 ++decodeControlMispred;
391 // Might want to set some sort of boolean and just do
392 // a check at the end
397 // Go ahead and compute any PC-relative branches.
399 if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
401 inst->setNextPC(inst->branchTarget());
403 if (inst->mispredicted()) {
404 ++decodeBranchMispred;
405 // Might want to set some sort of boolean and just do
406 // a check at the end
412 // Normally can check if a direct branch has the right target
413 // addr (either the immediate, or the branch PC + 4) and redirect
414 // fetch if it's incorrect.
416 // Increment which instruction we're looking at.
419 ++decodeDecodedInsts;