cpu: `Minor' in-order CPU model
[gem5.git] / src / cpu / minor / dyn_inst.cc
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 <iomanip>
41 #include <sstream>
42
43 #include "arch/isa.hh"
44 #include "arch/registers.hh"
45 #include "cpu/minor/dyn_inst.hh"
46 #include "cpu/minor/trace.hh"
47 #include "cpu/base.hh"
48 #include "cpu/reg_class.hh"
49 #include "debug/MinorExecute.hh"
50 #include "enums/OpClass.hh"
51
52 namespace Minor
53 {
54
55 std::ostream &
56 operator <<(std::ostream &os, const InstId &id)
57 {
58 os << id.threadId << '/' << id.streamSeqNum << '.'
59 << id.predictionSeqNum << '/' << id.lineSeqNum;
60
61 /* Not all structures have fetch and exec sequence numbers */
62 if (id.fetchSeqNum != 0) {
63 os << '/' << id.fetchSeqNum;
64 if (id.execSeqNum != 0)
65 os << '.' << id.execSeqNum;
66 }
67
68 return os;
69 }
70
71 MinorDynInstPtr MinorDynInst::bubbleInst = NULL;
72
73 void
74 MinorDynInst::init()
75 {
76 if (!bubbleInst) {
77 bubbleInst = new MinorDynInst();
78 assert(bubbleInst->isBubble());
79 /* Make bubbleInst immortal */
80 bubbleInst->incref();
81 }
82 }
83
84 bool
85 MinorDynInst::isLastOpInInst() const
86 {
87 assert(staticInst);
88 return !(staticInst->isMicroop() && !staticInst->isLastMicroop());
89 }
90
91 bool
92 MinorDynInst::isNoCostInst() const
93 {
94 return isInst() && staticInst->opClass() == No_OpClass;
95 }
96
97 void
98 MinorDynInst::reportData(std::ostream &os) const
99 {
100 if (isBubble())
101 os << "-";
102 else if (isFault())
103 os << "F;" << id;
104 else
105 os << id;
106 }
107
108 std::ostream &
109 operator <<(std::ostream &os, const MinorDynInst &inst)
110 {
111 os << inst.id << " pc: 0x"
112 << std::hex << inst.pc.instAddr() << std::dec << " (";
113
114 if (inst.isFault())
115 os << "fault: \"" << inst.fault->name() << '"';
116 else if (inst.staticInst)
117 os << inst.staticInst->getName();
118 else
119 os << "bubble";
120
121 os << ')';
122
123 return os;
124 }
125
126 /** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer,
127 * float, misc and zero registers given an 'architectural register number' */
128 static void
129 printRegName(std::ostream &os, TheISA::RegIndex reg)
130 {
131 RegClass reg_class = regIdxToClass(reg);
132
133 switch (reg_class)
134 {
135 case MiscRegClass:
136 {
137 TheISA::RegIndex misc_reg = reg - TheISA::Misc_Reg_Base;
138
139 /* This is an ugly test because not all archs. have miscRegName */
140 #if THE_ISA == ARM_ISA
141 os << 'm' << misc_reg << '(' << TheISA::miscRegName[misc_reg] <<
142 ')';
143 #else
144 os << 'n' << misc_reg;
145 #endif
146 }
147 break;
148 case FloatRegClass:
149 os << 'f' << static_cast<unsigned int>(reg - TheISA::FP_Reg_Base);
150 break;
151 case IntRegClass:
152 if (reg == TheISA::ZeroReg) {
153 os << 'z';
154 } else {
155 os << 'r' << static_cast<unsigned int>(reg);
156 }
157 break;
158 case CCRegClass:
159 os << 'c' << static_cast<unsigned int>(reg - TheISA::CC_Reg_Base);
160 }
161 }
162
163 void
164 MinorDynInst::minorTraceInst(const Named &named_object) const
165 {
166 if (isFault()) {
167 MINORINST(&named_object, "id=F;%s addr=0x%x fault=\"%s\"\n",
168 id, pc.instAddr(), fault->name());
169 } else {
170 unsigned int num_src_regs = staticInst->numSrcRegs();
171 unsigned int num_dest_regs = staticInst->numDestRegs();
172
173 std::ostringstream regs_str;
174
175 /* Format lists of src and dest registers for microops and
176 * 'full' instructions */
177 if (!staticInst->isMacroop()) {
178 regs_str << " srcRegs=";
179
180 unsigned int src_reg = 0;
181 while (src_reg < num_src_regs) {
182 printRegName(regs_str, staticInst->srcRegIdx(src_reg));
183
184 src_reg++;
185 if (src_reg != num_src_regs)
186 regs_str << ',';
187 }
188
189 regs_str << " destRegs=";
190
191 unsigned int dest_reg = 0;
192 while (dest_reg < num_dest_regs) {
193 printRegName(regs_str, staticInst->destRegIdx(dest_reg));
194
195 dest_reg++;
196 if (dest_reg != num_dest_regs)
197 regs_str << ',';
198 }
199
200 #if THE_ISA == ARM_ISA
201 regs_str << " extMachInst=" << std::hex << std::setw(16)
202 << std::setfill('0') << staticInst->machInst << std::dec;
203 #endif
204 }
205
206 std::ostringstream flags;
207 staticInst->printFlags(flags, " ");
208
209 MINORINST(&named_object, "id=%s addr=0x%x inst=\"%s\" class=%s"
210 " flags=\"%s\"%s%s\n",
211 id, pc.instAddr(),
212 (staticInst->opClass() == No_OpClass ?
213 "(invalid)" : staticInst->disassemble(0,NULL)),
214 Enums::OpClassStrings[staticInst->opClass()],
215 flags.str(),
216 regs_str.str(),
217 (predictedTaken ? " predictedTaken" : ""));
218 }
219 }
220
221 MinorDynInst::~MinorDynInst()
222 {
223 if (traceData)
224 delete traceData;
225 }
226
227 }