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