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/pipe_data.hh"
41
42namespace Minor
43{
44
45std::ostream &
46operator <<(std::ostream &os, BranchData::Reason reason)
47{
48    switch (reason)
49    {
50      case BranchData::NoBranch:
51        os << "NoBranch";
52        break;
53      case BranchData::UnpredictedBranch:
54        os << "UnpredictedBranch";
55        break;
56      case BranchData::BranchPrediction:
57        os << "BranchPrediction";
58        break;
59      case BranchData::CorrectlyPredictedBranch:
60        os << "CorrectlyPredictedBranch";
61        break;
62      case BranchData::BadlyPredictedBranch:
63        os << "BadlyPredictedBranch";
64        break;
65      case BranchData::BadlyPredictedBranchTarget:
66        os << "BadlyPredictedBranchTarget";
67        break;
68      case BranchData::Interrupt:
69        os << "Interrupt";
70        break;
71      case BranchData::SuspendThread:
72        os << "SuspendThread";
73        break;
74      case BranchData::HaltFetch:
75        os << "HaltFetch";
76        break;
77    }
78
79    return os;
80}
81
82bool
83BranchData::isStreamChange(const BranchData::Reason reason)
84{
85    bool ret = false;
86
87    switch (reason)
88    {
89        /* No change of stream (see the enum comment in pipe_data.hh) */
90      case NoBranch:
91      case CorrectlyPredictedBranch:
92        ret = false;
93        break;
94
95        /* Change of stream (Fetch1 should act on) */
96      case UnpredictedBranch:
97      case BranchPrediction:
98      case BadlyPredictedBranchTarget:
99      case BadlyPredictedBranch:
100      case SuspendThread:
101      case Interrupt:
102      case HaltFetch:
103        ret = true;
104        break;
105    }
106
107    return ret;
108}
109
110bool
111BranchData::isBranch(const BranchData::Reason reason)
112{
113    bool ret = false;
114
115    switch (reason)
116    {
117        /* No change of stream (see the enum comment in pipe_data.hh) */
118      case NoBranch:
119      case CorrectlyPredictedBranch:
120      case SuspendThread:
121      case Interrupt:
122      case HaltFetch:
123        ret = false;
124        break;
125
126        /* Change of stream (Fetch1 should act on) */
127      case UnpredictedBranch:
128      case BranchPrediction:
129      case BadlyPredictedBranchTarget:
130      case BadlyPredictedBranch:
131        ret = true;
132        break;
133    }
134
135    return ret;
136}
137
138void
139BranchData::reportData(std::ostream &os) const
140{
141    if (isBubble()) {
142        os << '-';
143    } else {
144        os << reason
145            << ';' << newStreamSeqNum << '.' << newPredictionSeqNum
146            << ";0x" << std::hex << target.instAddr() << std::dec
147            << ';';
148        inst->reportData(os);
149    }
150}
151
152std::ostream &
153operator <<(std::ostream &os, const BranchData &branch)
154{
155    os << branch.reason << " target: 0x"
156        << std::hex << branch.target.instAddr() << std::dec
157        << ' ' << *branch.inst
158        << ' ' << branch.newStreamSeqNum << "(stream)."
159        << branch.newPredictionSeqNum << "(pred)";
160
161    return os;
162}
163
164void
165ForwardLineData::setFault(Fault fault_)
166{
167    fault = fault_;
168    if (isFault())
169        bubbleFlag = false;
170}
171
172void
173ForwardLineData::allocateLine(unsigned int width_)
174{
175    lineWidth = width_;
176    bubbleFlag = false;
177
178    assert(!isFault());
179    assert(!line);
180
181    line = new uint8_t[width_];
182}
183
184void
185ForwardLineData::adoptPacketData(Packet *packet)
186{
187    this->packet = packet;
188    lineWidth = packet->req->getSize();
189    bubbleFlag = false;
190
191    assert(!isFault());
192    assert(!line);
193
194    line = packet->getPtr<uint8_t>();
195}
196
197void
198ForwardLineData::freeLine()
199{
200    /* Only free lines in non-faulting, non-bubble lines */
201    if (!isFault() && !isBubble()) {
202        assert(line);
203        /* If packet is not NULL then the line must belong to the packet so
204         *  we don't need to separately deallocate the line */
205        if (packet) {
206            delete packet;
207        } else {
208            delete [] line;
209        }
210        line = NULL;
211        bubbleFlag = true;
212    }
213}
214
215void
216ForwardLineData::reportData(std::ostream &os) const
217{
218    if (isBubble())
219        os << '-';
220    else if (fault != NoFault)
221        os << "F;" << id;
222    else
223        os << id;
224}
225
226ForwardInstData::ForwardInstData(unsigned int width, ThreadID tid) :
227    numInsts(width), threadId(tid)
228{
229    bubbleFill();
230}
231
232ForwardInstData::ForwardInstData(const ForwardInstData &src)
233{
234    *this = src;
235}
236
237ForwardInstData &
238ForwardInstData::operator =(const ForwardInstData &src)
239{
240    numInsts = src.numInsts;
241
242    for (unsigned int i = 0; i < src.numInsts; i++)
243        insts[i] = src.insts[i];
244
245    return *this;
246}
247
248bool
249ForwardInstData::isBubble() const
250{
251    return numInsts == 0 || insts[0]->isBubble();
252}
253
254void
255ForwardInstData::bubbleFill()
256{
257    for (unsigned int i = 0; i < numInsts; i++)
258        insts[i] = MinorDynInst::bubble();
259}
260
261void
262ForwardInstData::resize(unsigned int width)
263{
264    assert(width < MAX_FORWARD_INSTS);
265    numInsts = width;
266
267    bubbleFill();
268}
269
270void
271ForwardInstData::reportData(std::ostream &os) const
272{
273    if (isBubble()) {
274        os << '-';
275    } else {
276        unsigned int i = 0;
277
278        os << '(';
279        while (i != numInsts) {
280            insts[i]->reportData(os);
281            i++;
282            if (i != numInsts)
283                os << ',';
284        }
285        os << ')';
286    }
287}
288
289}
290