cpu: add a condition-code register class
[gem5.git] / src / cpu / inorder / thread_context.hh
1 /*
2 * Copyright (c) 2012 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) 2007 MIPS Technologies, Inc.
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: Korey Sewell
42 *
43 */
44
45 #ifndef __CPU_INORDER_THREAD_CONTEXT_HH__
46 #define __CPU_INORDER_THREAD_CONTEXT_HH__
47
48 #include "config/the_isa.hh"
49 #include "cpu/inorder/cpu.hh"
50 #include "cpu/inorder/thread_state.hh"
51 #include "cpu/exetrace.hh"
52 #include "cpu/thread_context.hh"
53 #include "arch/kernel_stats.hh"
54
55 class EndQuiesceEvent;
56 class CheckerCPU;
57 namespace Kernel {
58 class Statistics;
59 };
60
61 /**
62 * Derived ThreadContext class for use with the InOrderCPU. It
63 * provides the interface for any external objects to access a
64 * single thread's state and some general CPU state. Any time
65 * external objects try to update state through this interface,
66 * the CPU will create an event to squash all in-flight
67 * instructions in order to ensure state is maintained correctly.
68 * It must be defined specifically for the InOrderCPU because
69 * not all architectural state is located within the O3ThreadState
70 * (such as the commit PC, and registers), and specific actions
71 * must be taken when using this interface (such as squashing all
72 * in-flight instructions when doing a write to this interface).
73 */
74 class InOrderThreadContext : public ThreadContext
75 {
76 public:
77 InOrderThreadContext() { }
78
79 /** Pointer to the CPU. */
80 InOrderCPU *cpu;
81
82 /** Pointer to the thread state that this TC corrseponds to. */
83 InOrderThreadState *thread;
84
85 /** Returns a pointer to the ITB. */
86 /** @TODO: PERF: Should we bind this to a pointer in constructor? */
87 TheISA::TLB *getITBPtr() { return cpu->getITBPtr(); }
88
89 /** Returns a pointer to the DTB. */
90 /** @TODO: PERF: Should we bind this to a pointer in constructor? */
91 TheISA::TLB *getDTBPtr() { return cpu->getDTBPtr(); }
92
93 /** Currently InOrder model does not support CheckerCPU, this is
94 * merely here for supporting compilation of gem5 with the Checker
95 * as a runtime option
96 */
97 CheckerCPU *getCheckerCpuPtr() { return NULL; }
98
99 TheISA::Decoder *
100 getDecoderPtr()
101 {
102 return cpu->getDecoderPtr(thread->contextId());
103 }
104
105 System *getSystemPtr() { return cpu->system; }
106
107 /** Returns a pointer to this CPU. */
108 BaseCPU *getCpuPtr() { return cpu; }
109
110 /** Returns a pointer to this CPU. */
111 std::string getCpuName() { return cpu->name(); }
112
113 /** Reads this CPU's ID. */
114 int cpuId() { return cpu->cpuId(); }
115
116 int contextId() { return thread->contextId(); }
117
118 void setContextId(int id) { thread->setContextId(id); }
119
120 /** Returns this thread's ID number. */
121 int threadId() { return thread->threadId(); }
122 void setThreadId(int id) { return thread->setThreadId(id); }
123
124 uint64_t readMicroPC()
125 { return 0; }
126
127 void setMicroPC(uint64_t val) { };
128
129 uint64_t readNextMicroPC()
130 { return 0; }
131
132 void setNextMicroPC(uint64_t val) { };
133
134 /** Returns a pointer to this thread's kernel statistics. */
135 TheISA::Kernel::Statistics *getKernelStats()
136 { return thread->kernelStats; }
137
138 PortProxy &getPhysProxy() { return thread->getPhysProxy(); }
139
140 FSTranslatingPortProxy &getVirtProxy();
141
142 void initMemProxies(ThreadContext *tc)
143 { thread->initMemProxies(tc); }
144
145 /** Dumps the function profiling information.
146 * @todo: Implement.
147 */
148 void dumpFuncProfile();
149
150 /** Reads the last tick that this thread was activated on. */
151 Tick readLastActivate();
152 /** Reads the last tick that this thread was suspended on. */
153 Tick readLastSuspend();
154
155 /** Clears the function profiling information. */
156 void profileClear();
157
158 /** Samples the function profiling information. */
159 void profileSample();
160
161 /** Returns pointer to the quiesce event. */
162 EndQuiesceEvent *getQuiesceEvent()
163 {
164 return this->thread->quiesceEvent;
165 }
166
167 SETranslatingPortProxy &getMemProxy() { return thread->getMemProxy(); }
168
169 /** Returns a pointer to this thread's process. */
170 Process *getProcessPtr() { return thread->getProcessPtr(); }
171
172 /** Returns this thread's status. */
173 Status status() const { return thread->status(); }
174
175 /** Sets this thread's status. */
176 void setStatus(Status new_status)
177 { thread->setStatus(new_status); }
178
179 /** Set the status to Active. Optional delay indicates number of
180 * cycles to wait before beginning execution. */
181 void activate(Cycles delay = Cycles(1));
182
183 /** Set the status to Suspended. */
184 void suspend(Cycles delay = Cycles(0));
185
186 /** Set the status to Halted. */
187 void halt(Cycles delay = Cycles(0));
188
189 /** Takes over execution of a thread from another CPU. */
190 void takeOverFrom(ThreadContext *old_context);
191
192 /** Registers statistics associated with this TC. */
193 void regStats(const std::string &name);
194
195 /** Returns this thread's ID number. */
196 int getThreadNum() { return thread->threadId(); }
197
198 /** Copies the architectural registers from another TC into this TC. */
199 void copyArchRegs(ThreadContext *src_tc);
200
201 /** Resets all architectural registers to 0. */
202 void clearArchRegs();
203
204 /** Reads an integer register. */
205 uint64_t readIntReg(int reg_idx);
206
207 FloatReg readFloatReg(int reg_idx);
208
209 FloatRegBits readFloatRegBits(int reg_idx);
210
211 CCReg readCCReg(int reg_idx);
212
213 uint64_t readRegOtherThread(int misc_reg, ThreadID tid);
214
215 /** Sets an integer register to a value. */
216 void setIntReg(int reg_idx, uint64_t val);
217
218 void setFloatReg(int reg_idx, FloatReg val);
219
220 void setFloatRegBits(int reg_idx, FloatRegBits val);
221
222 void setCCReg(int reg_idx, CCReg val);
223
224 void setRegOtherThread(int misc_reg,
225 const MiscReg &val,
226 ThreadID tid);
227
228 /** Reads this thread's PC. */
229 TheISA::PCState pcState()
230 { return cpu->pcState(thread->threadId()); }
231
232 /** Sets this thread's PC. */
233 void pcState(const TheISA::PCState &val)
234 { cpu->pcState(val, thread->threadId()); }
235
236 /** Needs to be implemented for future CheckerCPU support.
237 * See O3CPU for examples on how to integrate Checker.
238 */
239 void pcStateNoRecord(const TheISA::PCState &val)
240 {}
241
242 Addr instAddr()
243 { return cpu->instAddr(thread->threadId()); }
244
245 Addr nextInstAddr()
246 { return cpu->nextInstAddr(thread->threadId()); }
247
248 MicroPC microPC()
249 { return cpu->microPC(thread->threadId()); }
250
251 /** Reads a miscellaneous register. */
252 MiscReg readMiscRegNoEffect(int misc_reg)
253 { return cpu->readMiscRegNoEffect(misc_reg, thread->threadId()); }
254
255 /** Reads a misc. register, including any side-effects the
256 * read might have as defined by the architecture. */
257 MiscReg readMiscReg(int misc_reg)
258 { return cpu->readMiscReg(misc_reg, thread->threadId()); }
259
260 /** Sets a misc. register. */
261 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
262
263 /** Sets a misc. register, including any side-effects the
264 * write might have as defined by the architecture. */
265 void setMiscReg(int misc_reg, const MiscReg &val);
266
267 int flattenIntIndex(int reg)
268 { return cpu->isa[thread->threadId()]->flattenIntIndex(reg); }
269
270 int flattenFloatIndex(int reg)
271 { return cpu->isa[thread->threadId()]->flattenFloatIndex(reg); }
272
273 int flattenCCIndex(int reg)
274 { return cpu->isa[thread->threadId()]->flattenCCIndex(reg); }
275
276 void activateContext(Cycles delay)
277 { cpu->activateContext(thread->threadId(), delay); }
278
279 void deallocateContext()
280 { cpu->deallocateContext(thread->threadId()); }
281
282 /** Returns the number of consecutive store conditional failures. */
283 // @todo: Figure out where these store cond failures should go.
284 unsigned readStCondFailures()
285 { return thread->storeCondFailures; }
286
287 /** Sets the number of consecutive store conditional failures. */
288 void setStCondFailures(unsigned sc_failures)
289 { thread->storeCondFailures = sc_failures; }
290
291 // Only really makes sense for old CPU model. Lots of code
292 // outside the CPU still checks this function, so it will
293 // always return false to keep everything working.
294 /** Checks if the thread is misspeculating. Because it is
295 * very difficult to determine if the thread is
296 * misspeculating, this is set as false. */
297 bool misspeculating() { return false; }
298
299 /** Executes a syscall in SE mode. */
300 void syscall(int64_t callnum)
301 { return cpu->syscall(callnum, thread->threadId()); }
302
303 /** Reads the funcExeInst counter. */
304 Counter readFuncExeInst() { return thread->funcExeInst; }
305
306 void changeRegFileContext(unsigned param,
307 unsigned val)
308 { panic("Not supported!"); }
309
310 uint64_t readIntRegFlat(int idx);
311 void setIntRegFlat(int idx, uint64_t val);
312
313 FloatReg readFloatRegFlat(int idx);
314 void setFloatRegFlat(int idx, FloatReg val);
315
316 FloatRegBits readFloatRegBitsFlat(int idx);
317 void setFloatRegBitsFlat(int idx, FloatRegBits val);
318
319 CCReg readCCRegFlat(int idx);
320 void setCCRegFlat(int idx, CCReg val);
321 };
322
323 #endif