dyn_inst.hh (12385:288c62455dde) dyn_inst.hh (12622:91cce46512f2)
1/*
2 * Copyright (c) 2010, 2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 */
43
44#ifndef __CPU_O3_DYN_INST_HH__
45#define __CPU_O3_DYN_INST_HH__
46
47#include <array>
48
49#include "arch/isa_traits.hh"
50#include "config/the_isa.hh"
51#include "cpu/o3/cpu.hh"
52#include "cpu/o3/isa_specific.hh"
53#include "cpu/base_dyn_inst.hh"
54#include "cpu/inst_seq.hh"
55#include "cpu/reg_class.hh"
56
57class Packet;
58
59template <class Impl>
60class BaseO3DynInst : public BaseDynInst<Impl>
61{
62 public:
63 /** Typedef for the CPU. */
64 typedef typename Impl::O3CPU O3CPU;
65
66 /** Binary machine instruction type. */
67 typedef TheISA::MachInst MachInst;
1/*
2 * Copyright (c) 2010, 2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 */
43
44#ifndef __CPU_O3_DYN_INST_HH__
45#define __CPU_O3_DYN_INST_HH__
46
47#include <array>
48
49#include "arch/isa_traits.hh"
50#include "config/the_isa.hh"
51#include "cpu/o3/cpu.hh"
52#include "cpu/o3/isa_specific.hh"
53#include "cpu/base_dyn_inst.hh"
54#include "cpu/inst_seq.hh"
55#include "cpu/reg_class.hh"
56
57class Packet;
58
59template <class Impl>
60class BaseO3DynInst : public BaseDynInst<Impl>
61{
62 public:
63 /** Typedef for the CPU. */
64 typedef typename Impl::O3CPU O3CPU;
65
66 /** Binary machine instruction type. */
67 typedef TheISA::MachInst MachInst;
68 /** Extended machine instruction type. */
69 typedef TheISA::ExtMachInst ExtMachInst;
70 /** Register types. */
71 typedef TheISA::IntReg IntReg;
72 typedef TheISA::FloatReg FloatReg;
73 typedef TheISA::FloatRegBits FloatRegBits;
74 typedef TheISA::CCReg CCReg;
75 using VecRegContainer = TheISA::VecRegContainer;
76 using VecElem = TheISA::VecElem;
77 static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg;
78
79 /** Misc register type. */
80 typedef TheISA::MiscReg MiscReg;
81
82 enum {
83 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
84 MaxInstDestRegs = TheISA::MaxInstDestRegs //< Max dest regs
85 };
86
87 public:
88 /** BaseDynInst constructor given a binary instruction. */
89 BaseO3DynInst(const StaticInstPtr &staticInst, const StaticInstPtr
90 &macroop, TheISA::PCState pc, TheISA::PCState predPC,
91 InstSeqNum seq_num, O3CPU *cpu);
92
93 /** BaseDynInst constructor given a static inst pointer. */
94 BaseO3DynInst(const StaticInstPtr &_staticInst,
95 const StaticInstPtr &_macroop);
96
97 ~BaseO3DynInst();
98
99 /** Executes the instruction.*/
100 Fault execute();
101
102 /** Initiates the access. Only valid for memory operations. */
103 Fault initiateAcc();
104
105 /** Completes the access. Only valid for memory operations. */
106 Fault completeAcc(PacketPtr pkt);
107
108 private:
109 /** Initializes variables. */
110 void initVars();
111
112 protected:
113 /** Explicitation of dependent names. */
114 using BaseDynInst<Impl>::cpu;
115 using BaseDynInst<Impl>::_srcRegIdx;
116 using BaseDynInst<Impl>::_destRegIdx;
117
118 /** Values to be written to the destination misc. registers. */
119 std::array<MiscReg, TheISA::MaxMiscDestRegs> _destMiscRegVal;
120
121 /** Indexes of the destination misc. registers. They are needed to defer
122 * the write accesses to the misc. registers until the commit stage, when
123 * the instruction is out of its speculative state.
124 */
125 std::array<short, TheISA::MaxMiscDestRegs> _destMiscRegIdx;
126
127 /** Number of destination misc. registers. */
128 uint8_t _numDestMiscRegs;
129
130
131 public:
132#if TRACING_ON
133 /** Tick records used for the pipeline activity viewer. */
134 Tick fetchTick; // instruction fetch is completed.
135 int32_t decodeTick; // instruction enters decode phase
136 int32_t renameTick; // instruction enters rename phase
137 int32_t dispatchTick;
138 int32_t issueTick;
139 int32_t completeTick;
140 int32_t commitTick;
141 int32_t storeTick;
142#endif
143
144 /** Reads a misc. register, including any side-effects the read
145 * might have as defined by the architecture.
146 */
147 MiscReg readMiscReg(int misc_reg)
148 {
149 return this->cpu->readMiscReg(misc_reg, this->threadNumber);
150 }
151
152 /** Sets a misc. register, including any side-effects the write
153 * might have as defined by the architecture.
154 */
155 void setMiscReg(int misc_reg, const MiscReg &val)
156 {
157 /** Writes to misc. registers are recorded and deferred until the
158 * commit stage, when updateMiscRegs() is called. First, check if
159 * the misc reg has been written before and update its value to be
160 * committed instead of making a new entry. If not, make a new
161 * entry and record the write.
162 */
163 for (int idx = 0; idx < _numDestMiscRegs; idx++) {
164 if (_destMiscRegIdx[idx] == misc_reg) {
165 _destMiscRegVal[idx] = val;
166 return;
167 }
168 }
169
170 assert(_numDestMiscRegs < TheISA::MaxMiscDestRegs);
171 _destMiscRegIdx[_numDestMiscRegs] = misc_reg;
172 _destMiscRegVal[_numDestMiscRegs] = val;
173 _numDestMiscRegs++;
174 }
175
176 /** Reads a misc. register, including any side-effects the read
177 * might have as defined by the architecture.
178 */
179 TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
180 {
181 const RegId& reg = si->srcRegIdx(idx);
182 assert(reg.isMiscReg());
183 return this->cpu->readMiscReg(reg.index(), this->threadNumber);
184 }
185
186 /** Sets a misc. register, including any side-effects the write
187 * might have as defined by the architecture.
188 */
189 void setMiscRegOperand(const StaticInst *si, int idx,
190 const MiscReg &val)
191 {
192 const RegId& reg = si->destRegIdx(idx);
193 assert(reg.isMiscReg());
194 setMiscReg(reg.index(), val);
195 }
196
197 /** Called at the commit stage to update the misc. registers. */
198 void updateMiscRegs()
199 {
200 // @todo: Pretty convoluted way to avoid squashing from happening when
201 // using the TC during an instruction's execution (specifically for
202 // instructions that have side-effects that use the TC). Fix this.
203 // See cpu/o3/dyn_inst_impl.hh.
204 bool no_squash_from_TC = this->thread->noSquashFromTC;
205 this->thread->noSquashFromTC = true;
206
207 for (int i = 0; i < _numDestMiscRegs; i++)
208 this->cpu->setMiscReg(
209 _destMiscRegIdx[i], _destMiscRegVal[i], this->threadNumber);
210
211 this->thread->noSquashFromTC = no_squash_from_TC;
212 }
213
214 void forwardOldRegs()
215 {
216
217 for (int idx = 0; idx < this->numDestRegs(); idx++) {
218 PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx);
219 const RegId& original_dest_reg =
220 this->staticInst->destRegIdx(idx);
221 switch (original_dest_reg.classValue()) {
222 case IntRegClass:
223 this->setIntRegOperand(this->staticInst.get(), idx,
224 this->cpu->readIntReg(prev_phys_reg));
225 break;
226 case FloatRegClass:
227 this->setFloatRegOperandBits(this->staticInst.get(), idx,
228 this->cpu->readFloatRegBits(prev_phys_reg));
229 break;
230 case VecRegClass:
231 this->setVecRegOperand(this->staticInst.get(), idx,
232 this->cpu->readVecReg(prev_phys_reg));
233 break;
234 case VecElemClass:
235 this->setVecElemOperand(this->staticInst.get(), idx,
236 this->cpu->readVecElem(prev_phys_reg));
237 break;
238 case CCRegClass:
239 this->setCCRegOperand(this->staticInst.get(), idx,
240 this->cpu->readCCReg(prev_phys_reg));
241 break;
242 case MiscRegClass:
243 // no need to forward misc reg values
244 break;
245 default:
246 panic("Unknown register class: %d",
247 (int)original_dest_reg.classValue());
248 }
249 }
250 }
251 /** Calls hardware return from error interrupt. */
252 Fault hwrei();
253 /** Traps to handle specified fault. */
254 void trap(const Fault &fault);
255 bool simPalCheck(int palFunc);
256
257 /** Emulates a syscall. */
258 void syscall(int64_t callnum, Fault *fault);
259
260 public:
261
262 // The register accessor methods provide the index of the
263 // instruction's operand (e.g., 0 or 1), not the architectural
264 // register index, to simplify the implementation of register
265 // renaming. We find the architectural register index by indexing
266 // into the instruction's own operand index table. Note that a
267 // raw pointer to the StaticInst is provided instead of a
268 // ref-counted StaticInstPtr to redice overhead. This is fine as
269 // long as these methods don't copy the pointer into any long-term
270 // storage (which is pretty hard to imagine they would have reason
271 // to do).
272
273 IntReg readIntRegOperand(const StaticInst *si, int idx)
274 {
275 return this->cpu->readIntReg(this->_srcRegIdx[idx]);
276 }
277
278 FloatReg readFloatRegOperand(const StaticInst *si, int idx)
279 {
280 return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
281 }
282
283 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
284 {
285 return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
286 }
287
288 const VecRegContainer&
289 readVecRegOperand(const StaticInst *si, int idx) const
290 {
291 return this->cpu->readVecReg(this->_srcRegIdx[idx]);
292 }
293
294 /**
295 * Read destination vector register operand for modification.
296 */
297 VecRegContainer&
298 getWritableVecRegOperand(const StaticInst *si, int idx)
299 {
300 return this->cpu->getWritableVecReg(this->_destRegIdx[idx]);
301 }
302
303 /** Vector Register Lane Interfaces. */
304 /** @{ */
305 /** Reads source vector 8bit operand. */
306 ConstVecLane8
307 readVec8BitLaneOperand(const StaticInst *si, int idx) const
308 {
309 return cpu->template readVecLane<uint8_t>(_srcRegIdx[idx]);
310 }
311
312 /** Reads source vector 16bit operand. */
313 ConstVecLane16
314 readVec16BitLaneOperand(const StaticInst *si, int idx) const
315 {
316 return cpu->template readVecLane<uint16_t>(_srcRegIdx[idx]);
317 }
318
319 /** Reads source vector 32bit operand. */
320 ConstVecLane32
321 readVec32BitLaneOperand(const StaticInst *si, int idx) const
322 {
323 return cpu->template readVecLane<uint32_t>(_srcRegIdx[idx]);
324 }
325
326 /** Reads source vector 64bit operand. */
327 ConstVecLane64
328 readVec64BitLaneOperand(const StaticInst *si, int idx) const
329 {
330 return cpu->template readVecLane<uint64_t>(_srcRegIdx[idx]);
331 }
332
333 /** Write a lane of the destination vector operand. */
334 template <typename LD>
335 void
336 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
337 {
338 return cpu->template setVecLane(_destRegIdx[idx], val);
339 }
340 virtual void
341 setVecLaneOperand(const StaticInst *si, int idx,
342 const LaneData<LaneSize::Byte>& val)
343 {
344 return setVecLaneOperandT(si, idx, val);
345 }
346 virtual void
347 setVecLaneOperand(const StaticInst *si, int idx,
348 const LaneData<LaneSize::TwoByte>& val)
349 {
350 return setVecLaneOperandT(si, idx, val);
351 }
352 virtual void
353 setVecLaneOperand(const StaticInst *si, int idx,
354 const LaneData<LaneSize::FourByte>& val)
355 {
356 return setVecLaneOperandT(si, idx, val);
357 }
358 virtual void
359 setVecLaneOperand(const StaticInst *si, int idx,
360 const LaneData<LaneSize::EightByte>& val)
361 {
362 return setVecLaneOperandT(si, idx, val);
363 }
364 /** @} */
365
366 VecElem readVecElemOperand(const StaticInst *si, int idx) const
367 {
368 return this->cpu->readVecElem(this->_srcRegIdx[idx]);
369 }
370
371 CCReg readCCRegOperand(const StaticInst *si, int idx)
372 {
373 return this->cpu->readCCReg(this->_srcRegIdx[idx]);
374 }
375
376 /** @todo: Make results into arrays so they can handle multiple dest
377 * registers.
378 */
379 void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
380 {
381 this->cpu->setIntReg(this->_destRegIdx[idx], val);
382 BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
383 }
384
385 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
386 {
387 this->cpu->setFloatReg(this->_destRegIdx[idx], val);
388 BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
389 }
390
391 void setFloatRegOperandBits(const StaticInst *si, int idx,
392 FloatRegBits val)
393 {
394 this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
395 BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
396 }
397
398 void
399 setVecRegOperand(const StaticInst *si, int idx,
400 const VecRegContainer& val)
401 {
402 this->cpu->setVecReg(this->_destRegIdx[idx], val);
403 BaseDynInst<Impl>::setVecRegOperand(si, idx, val);
404 }
405
406 void setVecElemOperand(const StaticInst *si, int idx,
407 const VecElem val)
408 {
409 int reg_idx = idx;
410 this->cpu->setVecElem(this->_destRegIdx[reg_idx], val);
411 BaseDynInst<Impl>::setVecElemOperand(si, idx, val);
412 }
413
414 void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
415 {
416 this->cpu->setCCReg(this->_destRegIdx[idx], val);
417 BaseDynInst<Impl>::setCCRegOperand(si, idx, val);
418 }
419
420#if THE_ISA == MIPS_ISA
421 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid)
422 {
423 panic("MIPS MT not defined for O3 CPU.\n");
424 return 0;
425 }
426
427 void setRegOtherThread(const RegId& misc_reg, MiscReg val, ThreadID tid)
428 {
429 panic("MIPS MT not defined for O3 CPU.\n");
430 }
431#endif
432};
433
434#endif // __CPU_O3_ALPHA_DYN_INST_HH__
435
68 /** Register types. */
69 typedef TheISA::IntReg IntReg;
70 typedef TheISA::FloatReg FloatReg;
71 typedef TheISA::FloatRegBits FloatRegBits;
72 typedef TheISA::CCReg CCReg;
73 using VecRegContainer = TheISA::VecRegContainer;
74 using VecElem = TheISA::VecElem;
75 static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg;
76
77 /** Misc register type. */
78 typedef TheISA::MiscReg MiscReg;
79
80 enum {
81 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
82 MaxInstDestRegs = TheISA::MaxInstDestRegs //< Max dest regs
83 };
84
85 public:
86 /** BaseDynInst constructor given a binary instruction. */
87 BaseO3DynInst(const StaticInstPtr &staticInst, const StaticInstPtr
88 &macroop, TheISA::PCState pc, TheISA::PCState predPC,
89 InstSeqNum seq_num, O3CPU *cpu);
90
91 /** BaseDynInst constructor given a static inst pointer. */
92 BaseO3DynInst(const StaticInstPtr &_staticInst,
93 const StaticInstPtr &_macroop);
94
95 ~BaseO3DynInst();
96
97 /** Executes the instruction.*/
98 Fault execute();
99
100 /** Initiates the access. Only valid for memory operations. */
101 Fault initiateAcc();
102
103 /** Completes the access. Only valid for memory operations. */
104 Fault completeAcc(PacketPtr pkt);
105
106 private:
107 /** Initializes variables. */
108 void initVars();
109
110 protected:
111 /** Explicitation of dependent names. */
112 using BaseDynInst<Impl>::cpu;
113 using BaseDynInst<Impl>::_srcRegIdx;
114 using BaseDynInst<Impl>::_destRegIdx;
115
116 /** Values to be written to the destination misc. registers. */
117 std::array<MiscReg, TheISA::MaxMiscDestRegs> _destMiscRegVal;
118
119 /** Indexes of the destination misc. registers. They are needed to defer
120 * the write accesses to the misc. registers until the commit stage, when
121 * the instruction is out of its speculative state.
122 */
123 std::array<short, TheISA::MaxMiscDestRegs> _destMiscRegIdx;
124
125 /** Number of destination misc. registers. */
126 uint8_t _numDestMiscRegs;
127
128
129 public:
130#if TRACING_ON
131 /** Tick records used for the pipeline activity viewer. */
132 Tick fetchTick; // instruction fetch is completed.
133 int32_t decodeTick; // instruction enters decode phase
134 int32_t renameTick; // instruction enters rename phase
135 int32_t dispatchTick;
136 int32_t issueTick;
137 int32_t completeTick;
138 int32_t commitTick;
139 int32_t storeTick;
140#endif
141
142 /** Reads a misc. register, including any side-effects the read
143 * might have as defined by the architecture.
144 */
145 MiscReg readMiscReg(int misc_reg)
146 {
147 return this->cpu->readMiscReg(misc_reg, this->threadNumber);
148 }
149
150 /** Sets a misc. register, including any side-effects the write
151 * might have as defined by the architecture.
152 */
153 void setMiscReg(int misc_reg, const MiscReg &val)
154 {
155 /** Writes to misc. registers are recorded and deferred until the
156 * commit stage, when updateMiscRegs() is called. First, check if
157 * the misc reg has been written before and update its value to be
158 * committed instead of making a new entry. If not, make a new
159 * entry and record the write.
160 */
161 for (int idx = 0; idx < _numDestMiscRegs; idx++) {
162 if (_destMiscRegIdx[idx] == misc_reg) {
163 _destMiscRegVal[idx] = val;
164 return;
165 }
166 }
167
168 assert(_numDestMiscRegs < TheISA::MaxMiscDestRegs);
169 _destMiscRegIdx[_numDestMiscRegs] = misc_reg;
170 _destMiscRegVal[_numDestMiscRegs] = val;
171 _numDestMiscRegs++;
172 }
173
174 /** Reads a misc. register, including any side-effects the read
175 * might have as defined by the architecture.
176 */
177 TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
178 {
179 const RegId& reg = si->srcRegIdx(idx);
180 assert(reg.isMiscReg());
181 return this->cpu->readMiscReg(reg.index(), this->threadNumber);
182 }
183
184 /** Sets a misc. register, including any side-effects the write
185 * might have as defined by the architecture.
186 */
187 void setMiscRegOperand(const StaticInst *si, int idx,
188 const MiscReg &val)
189 {
190 const RegId& reg = si->destRegIdx(idx);
191 assert(reg.isMiscReg());
192 setMiscReg(reg.index(), val);
193 }
194
195 /** Called at the commit stage to update the misc. registers. */
196 void updateMiscRegs()
197 {
198 // @todo: Pretty convoluted way to avoid squashing from happening when
199 // using the TC during an instruction's execution (specifically for
200 // instructions that have side-effects that use the TC). Fix this.
201 // See cpu/o3/dyn_inst_impl.hh.
202 bool no_squash_from_TC = this->thread->noSquashFromTC;
203 this->thread->noSquashFromTC = true;
204
205 for (int i = 0; i < _numDestMiscRegs; i++)
206 this->cpu->setMiscReg(
207 _destMiscRegIdx[i], _destMiscRegVal[i], this->threadNumber);
208
209 this->thread->noSquashFromTC = no_squash_from_TC;
210 }
211
212 void forwardOldRegs()
213 {
214
215 for (int idx = 0; idx < this->numDestRegs(); idx++) {
216 PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx);
217 const RegId& original_dest_reg =
218 this->staticInst->destRegIdx(idx);
219 switch (original_dest_reg.classValue()) {
220 case IntRegClass:
221 this->setIntRegOperand(this->staticInst.get(), idx,
222 this->cpu->readIntReg(prev_phys_reg));
223 break;
224 case FloatRegClass:
225 this->setFloatRegOperandBits(this->staticInst.get(), idx,
226 this->cpu->readFloatRegBits(prev_phys_reg));
227 break;
228 case VecRegClass:
229 this->setVecRegOperand(this->staticInst.get(), idx,
230 this->cpu->readVecReg(prev_phys_reg));
231 break;
232 case VecElemClass:
233 this->setVecElemOperand(this->staticInst.get(), idx,
234 this->cpu->readVecElem(prev_phys_reg));
235 break;
236 case CCRegClass:
237 this->setCCRegOperand(this->staticInst.get(), idx,
238 this->cpu->readCCReg(prev_phys_reg));
239 break;
240 case MiscRegClass:
241 // no need to forward misc reg values
242 break;
243 default:
244 panic("Unknown register class: %d",
245 (int)original_dest_reg.classValue());
246 }
247 }
248 }
249 /** Calls hardware return from error interrupt. */
250 Fault hwrei();
251 /** Traps to handle specified fault. */
252 void trap(const Fault &fault);
253 bool simPalCheck(int palFunc);
254
255 /** Emulates a syscall. */
256 void syscall(int64_t callnum, Fault *fault);
257
258 public:
259
260 // The register accessor methods provide the index of the
261 // instruction's operand (e.g., 0 or 1), not the architectural
262 // register index, to simplify the implementation of register
263 // renaming. We find the architectural register index by indexing
264 // into the instruction's own operand index table. Note that a
265 // raw pointer to the StaticInst is provided instead of a
266 // ref-counted StaticInstPtr to redice overhead. This is fine as
267 // long as these methods don't copy the pointer into any long-term
268 // storage (which is pretty hard to imagine they would have reason
269 // to do).
270
271 IntReg readIntRegOperand(const StaticInst *si, int idx)
272 {
273 return this->cpu->readIntReg(this->_srcRegIdx[idx]);
274 }
275
276 FloatReg readFloatRegOperand(const StaticInst *si, int idx)
277 {
278 return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
279 }
280
281 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
282 {
283 return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
284 }
285
286 const VecRegContainer&
287 readVecRegOperand(const StaticInst *si, int idx) const
288 {
289 return this->cpu->readVecReg(this->_srcRegIdx[idx]);
290 }
291
292 /**
293 * Read destination vector register operand for modification.
294 */
295 VecRegContainer&
296 getWritableVecRegOperand(const StaticInst *si, int idx)
297 {
298 return this->cpu->getWritableVecReg(this->_destRegIdx[idx]);
299 }
300
301 /** Vector Register Lane Interfaces. */
302 /** @{ */
303 /** Reads source vector 8bit operand. */
304 ConstVecLane8
305 readVec8BitLaneOperand(const StaticInst *si, int idx) const
306 {
307 return cpu->template readVecLane<uint8_t>(_srcRegIdx[idx]);
308 }
309
310 /** Reads source vector 16bit operand. */
311 ConstVecLane16
312 readVec16BitLaneOperand(const StaticInst *si, int idx) const
313 {
314 return cpu->template readVecLane<uint16_t>(_srcRegIdx[idx]);
315 }
316
317 /** Reads source vector 32bit operand. */
318 ConstVecLane32
319 readVec32BitLaneOperand(const StaticInst *si, int idx) const
320 {
321 return cpu->template readVecLane<uint32_t>(_srcRegIdx[idx]);
322 }
323
324 /** Reads source vector 64bit operand. */
325 ConstVecLane64
326 readVec64BitLaneOperand(const StaticInst *si, int idx) const
327 {
328 return cpu->template readVecLane<uint64_t>(_srcRegIdx[idx]);
329 }
330
331 /** Write a lane of the destination vector operand. */
332 template <typename LD>
333 void
334 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
335 {
336 return cpu->template setVecLane(_destRegIdx[idx], val);
337 }
338 virtual void
339 setVecLaneOperand(const StaticInst *si, int idx,
340 const LaneData<LaneSize::Byte>& val)
341 {
342 return setVecLaneOperandT(si, idx, val);
343 }
344 virtual void
345 setVecLaneOperand(const StaticInst *si, int idx,
346 const LaneData<LaneSize::TwoByte>& val)
347 {
348 return setVecLaneOperandT(si, idx, val);
349 }
350 virtual void
351 setVecLaneOperand(const StaticInst *si, int idx,
352 const LaneData<LaneSize::FourByte>& val)
353 {
354 return setVecLaneOperandT(si, idx, val);
355 }
356 virtual void
357 setVecLaneOperand(const StaticInst *si, int idx,
358 const LaneData<LaneSize::EightByte>& val)
359 {
360 return setVecLaneOperandT(si, idx, val);
361 }
362 /** @} */
363
364 VecElem readVecElemOperand(const StaticInst *si, int idx) const
365 {
366 return this->cpu->readVecElem(this->_srcRegIdx[idx]);
367 }
368
369 CCReg readCCRegOperand(const StaticInst *si, int idx)
370 {
371 return this->cpu->readCCReg(this->_srcRegIdx[idx]);
372 }
373
374 /** @todo: Make results into arrays so they can handle multiple dest
375 * registers.
376 */
377 void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
378 {
379 this->cpu->setIntReg(this->_destRegIdx[idx], val);
380 BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
381 }
382
383 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
384 {
385 this->cpu->setFloatReg(this->_destRegIdx[idx], val);
386 BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
387 }
388
389 void setFloatRegOperandBits(const StaticInst *si, int idx,
390 FloatRegBits val)
391 {
392 this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
393 BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
394 }
395
396 void
397 setVecRegOperand(const StaticInst *si, int idx,
398 const VecRegContainer& val)
399 {
400 this->cpu->setVecReg(this->_destRegIdx[idx], val);
401 BaseDynInst<Impl>::setVecRegOperand(si, idx, val);
402 }
403
404 void setVecElemOperand(const StaticInst *si, int idx,
405 const VecElem val)
406 {
407 int reg_idx = idx;
408 this->cpu->setVecElem(this->_destRegIdx[reg_idx], val);
409 BaseDynInst<Impl>::setVecElemOperand(si, idx, val);
410 }
411
412 void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
413 {
414 this->cpu->setCCReg(this->_destRegIdx[idx], val);
415 BaseDynInst<Impl>::setCCRegOperand(si, idx, val);
416 }
417
418#if THE_ISA == MIPS_ISA
419 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid)
420 {
421 panic("MIPS MT not defined for O3 CPU.\n");
422 return 0;
423 }
424
425 void setRegOtherThread(const RegId& misc_reg, MiscReg val, ThreadID tid)
426 {
427 panic("MIPS MT not defined for O3 CPU.\n");
428 }
429#endif
430};
431
432#endif // __CPU_O3_ALPHA_DYN_INST_HH__
433