1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 * Korey Sewell 30 */ 31 32#include "cpu/o3/thread_context.hh" 33#include "cpu/quiesce_event.hh" 34 35#if FULL_SYSTEM 36template <class Impl> 37VirtualPort * 38O3ThreadContext<Impl>::getVirtPort(ThreadContext *src_tc) 39{ 40 if (!src_tc) 41 return thread->getVirtPort(); 42 43 VirtualPort *vp; 44 45 vp = new VirtualPort("tc-vport", src_tc); 46 thread->connectToMemFunc(vp); 47 return vp; 48} 49 50template <class Impl> 51void 52O3ThreadContext<Impl>::dumpFuncProfile() 53{ 54 thread->dumpFuncProfile(); 55} 56#endif 57 58template <class Impl> 59void 60O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context) 61{ 62 // some things should already be set up 63#if FULL_SYSTEM 64 assert(getSystemPtr() == old_context->getSystemPtr()); 65#else 66 assert(getProcessPtr() == old_context->getProcessPtr()); 67#endif 68 69 // copy over functional state 70 setStatus(old_context->status()); 71 copyArchRegs(old_context); 72 setCpuId(old_context->readCpuId()); 73 74#if !FULL_SYSTEM 75 thread->funcExeInst = old_context->readFuncExeInst(); 76#else 77 EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent(); 78 if (other_quiesce) { 79 // Point the quiesce event's TC at this TC so that it wakes up 80 // the proper CPU. 81 other_quiesce->tc = this; 82 } 83 if (thread->quiesceEvent) { 84 thread->quiesceEvent->tc = this; 85 } 86 87 // Transfer kernel stats from one CPU to the other. 88 thread->kernelStats = old_context->getKernelStats(); 89// storeCondFailures = 0; 90 cpu->lockFlag = false; 91#endif 92 93 old_context->setStatus(ThreadContext::Unallocated); 94 95 thread->inSyscall = false; 96 thread->trapPending = false; 97} 98 99#if FULL_SYSTEM 100template <class Impl> 101void 102O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp) 103{
| 1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 * Korey Sewell 30 */ 31 32#include "cpu/o3/thread_context.hh" 33#include "cpu/quiesce_event.hh" 34 35#if FULL_SYSTEM 36template <class Impl> 37VirtualPort * 38O3ThreadContext<Impl>::getVirtPort(ThreadContext *src_tc) 39{ 40 if (!src_tc) 41 return thread->getVirtPort(); 42 43 VirtualPort *vp; 44 45 vp = new VirtualPort("tc-vport", src_tc); 46 thread->connectToMemFunc(vp); 47 return vp; 48} 49 50template <class Impl> 51void 52O3ThreadContext<Impl>::dumpFuncProfile() 53{ 54 thread->dumpFuncProfile(); 55} 56#endif 57 58template <class Impl> 59void 60O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context) 61{ 62 // some things should already be set up 63#if FULL_SYSTEM 64 assert(getSystemPtr() == old_context->getSystemPtr()); 65#else 66 assert(getProcessPtr() == old_context->getProcessPtr()); 67#endif 68 69 // copy over functional state 70 setStatus(old_context->status()); 71 copyArchRegs(old_context); 72 setCpuId(old_context->readCpuId()); 73 74#if !FULL_SYSTEM 75 thread->funcExeInst = old_context->readFuncExeInst(); 76#else 77 EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent(); 78 if (other_quiesce) { 79 // Point the quiesce event's TC at this TC so that it wakes up 80 // the proper CPU. 81 other_quiesce->tc = this; 82 } 83 if (thread->quiesceEvent) { 84 thread->quiesceEvent->tc = this; 85 } 86 87 // Transfer kernel stats from one CPU to the other. 88 thread->kernelStats = old_context->getKernelStats(); 89// storeCondFailures = 0; 90 cpu->lockFlag = false; 91#endif 92 93 old_context->setStatus(ThreadContext::Unallocated); 94 95 thread->inSyscall = false; 96 thread->trapPending = false; 97} 98 99#if FULL_SYSTEM 100template <class Impl> 101void 102O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp) 103{
|
106} 107#endif 108 109template <class Impl> 110void 111O3ThreadContext<Impl>::activate(int delay) 112{ 113 DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", 114 getThreadNum()); 115 116 if (thread->status() == ThreadContext::Active) 117 return; 118 119#if FULL_SYSTEM 120 thread->lastActivate = curTick; 121#endif 122 123 if (thread->status() == ThreadContext::Unallocated) { 124 cpu->activateWhenReady(thread->readTid()); 125 return; 126 } 127 128 thread->setStatus(ThreadContext::Active); 129 130 // status() == Suspended 131 cpu->activateContext(thread->readTid(), delay); 132} 133 134template <class Impl> 135void 136O3ThreadContext<Impl>::suspend() 137{ 138 DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", 139 getThreadNum()); 140 141 if (thread->status() == ThreadContext::Suspended) 142 return; 143 144#if FULL_SYSTEM 145 thread->lastActivate = curTick; 146 thread->lastSuspend = curTick; 147#endif 148/* 149#if FULL_SYSTEM 150 // Don't change the status from active if there are pending interrupts 151 if (cpu->check_interrupts()) { 152 assert(status() == ThreadContext::Active); 153 return; 154 } 155#endif 156*/ 157 thread->setStatus(ThreadContext::Suspended); 158 cpu->suspendContext(thread->readTid()); 159} 160 161template <class Impl> 162void 163O3ThreadContext<Impl>::deallocate(int delay) 164{ 165 DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n", 166 getThreadNum(), delay); 167 168 if (thread->status() == ThreadContext::Unallocated) 169 return; 170 171 thread->setStatus(ThreadContext::Unallocated); 172 cpu->deallocateContext(thread->readTid(), true, delay); 173} 174 175template <class Impl> 176void 177O3ThreadContext<Impl>::halt() 178{ 179 DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", 180 getThreadNum()); 181 182 if (thread->status() == ThreadContext::Halted) 183 return; 184 185 thread->setStatus(ThreadContext::Halted); 186 cpu->haltContext(thread->readTid()); 187} 188 189template <class Impl> 190void 191O3ThreadContext<Impl>::regStats(const std::string &name) 192{ 193#if FULL_SYSTEM 194 thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system); 195 thread->kernelStats->regStats(name + ".kern"); 196#endif 197} 198 199template <class Impl> 200void 201O3ThreadContext<Impl>::serialize(std::ostream &os) 202{ 203#if FULL_SYSTEM 204 if (thread->kernelStats) 205 thread->kernelStats->serialize(os); 206#endif 207 208} 209 210template <class Impl> 211void 212O3ThreadContext<Impl>::unserialize(Checkpoint *cp, const std::string §ion) 213{ 214#if FULL_SYSTEM 215 if (thread->kernelStats) 216 thread->kernelStats->unserialize(cp, section); 217#endif 218 219} 220 221#if FULL_SYSTEM 222template <class Impl> 223Tick 224O3ThreadContext<Impl>::readLastActivate() 225{ 226 return thread->lastActivate; 227} 228 229template <class Impl> 230Tick 231O3ThreadContext<Impl>::readLastSuspend() 232{ 233 return thread->lastSuspend; 234} 235 236template <class Impl> 237void 238O3ThreadContext<Impl>::profileClear() 239{ 240 thread->profileClear(); 241} 242 243template <class Impl> 244void 245O3ThreadContext<Impl>::profileSample() 246{ 247 thread->profileSample(); 248} 249#endif 250 251template <class Impl> 252TheISA::MachInst 253O3ThreadContext<Impl>:: getInst() 254{ 255 return thread->getInst(); 256} 257 258template <class Impl> 259void 260O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc) 261{ 262 // This function will mess things up unless the ROB is empty and 263 // there are no instructions in the pipeline. 264 unsigned tid = thread->readTid(); 265 PhysRegIndex renamed_reg; 266 267 // First loop through the integer registers. 268 for (int i = 0; i < TheISA::NumIntRegs; ++i) { 269 renamed_reg = cpu->renameMap[tid].lookup(i); 270 271 DPRINTF(O3CPU, "Copying over register %i, had data %lli, " 272 "now has data %lli.\n", 273 renamed_reg, cpu->readIntReg(renamed_reg), 274 tc->readIntReg(i)); 275 276 cpu->setIntReg(renamed_reg, tc->readIntReg(i)); 277 } 278 279 // Then loop through the floating point registers. 280 for (int i = 0; i < TheISA::NumFloatRegs; ++i) { 281 renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag); 282 cpu->setFloatRegBits(renamed_reg, 283 tc->readFloatRegBits(i)); 284 } 285 286 // Copy the misc regs. 287 TheISA::copyMiscRegs(tc, this); 288 289 // Then finally set the PC and the next PC. 290 cpu->setPC(tc->readPC(), tid); 291 cpu->setNextPC(tc->readNextPC(), tid); 292#if !FULL_SYSTEM 293 this->thread->funcExeInst = tc->readFuncExeInst(); 294#endif 295} 296 297template <class Impl> 298void 299O3ThreadContext<Impl>::clearArchRegs() 300{} 301 302template <class Impl> 303uint64_t 304O3ThreadContext<Impl>::readIntReg(int reg_idx) 305{ 306 return cpu->readArchIntReg(reg_idx, thread->readTid()); 307} 308 309template <class Impl> 310TheISA::FloatReg 311O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width) 312{ 313 switch(width) { 314 case 32: 315 return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); 316 case 64: 317 return cpu->readArchFloatRegDouble(reg_idx, thread->readTid()); 318 default: 319 panic("Unsupported width!"); 320 return 0; 321 } 322} 323 324template <class Impl> 325TheISA::FloatReg 326O3ThreadContext<Impl>::readFloatReg(int reg_idx) 327{ 328 return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); 329} 330 331template <class Impl> 332TheISA::FloatRegBits 333O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width) 334{ 335 DPRINTF(Fault, "Reading floatint register through the TC!\n"); 336 return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); 337} 338 339template <class Impl> 340TheISA::FloatRegBits 341O3ThreadContext<Impl>::readFloatRegBits(int reg_idx) 342{ 343 return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); 344} 345 346template <class Impl> 347void 348O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val) 349{ 350 cpu->setArchIntReg(reg_idx, val, thread->readTid()); 351 352 // Squash if we're not already in a state update mode. 353 if (!thread->trapPending && !thread->inSyscall) { 354 cpu->squashFromTC(thread->readTid()); 355 } 356} 357 358template <class Impl> 359void 360O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width) 361{ 362 switch(width) { 363 case 32: 364 cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); 365 break; 366 case 64: 367 cpu->setArchFloatRegDouble(reg_idx, val, thread->readTid()); 368 break; 369 } 370 371 // Squash if we're not already in a state update mode. 372 if (!thread->trapPending && !thread->inSyscall) { 373 cpu->squashFromTC(thread->readTid()); 374 } 375} 376 377template <class Impl> 378void 379O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val) 380{ 381 cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); 382 383 if (!thread->trapPending && !thread->inSyscall) { 384 cpu->squashFromTC(thread->readTid()); 385 } 386} 387 388template <class Impl> 389void 390O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, 391 int width) 392{ 393 DPRINTF(Fault, "Setting floatint register through the TC!\n"); 394 cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); 395 396 // Squash if we're not already in a state update mode. 397 if (!thread->trapPending && !thread->inSyscall) { 398 cpu->squashFromTC(thread->readTid()); 399 } 400} 401 402template <class Impl> 403void 404O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) 405{ 406 cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); 407 408 // Squash if we're not already in a state update mode. 409 if (!thread->trapPending && !thread->inSyscall) { 410 cpu->squashFromTC(thread->readTid()); 411 } 412} 413 414template <class Impl> 415void 416O3ThreadContext<Impl>::setPC(uint64_t val) 417{ 418 cpu->setPC(val, thread->readTid()); 419 420 // Squash if we're not already in a state update mode. 421 if (!thread->trapPending && !thread->inSyscall) { 422 cpu->squashFromTC(thread->readTid()); 423 } 424} 425 426template <class Impl> 427void 428O3ThreadContext<Impl>::setNextPC(uint64_t val) 429{ 430 cpu->setNextPC(val, thread->readTid()); 431 432 // Squash if we're not already in a state update mode. 433 if (!thread->trapPending && !thread->inSyscall) { 434 cpu->squashFromTC(thread->readTid()); 435 } 436} 437 438template <class Impl> 439void 440O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val) 441{ 442 cpu->setMiscReg(misc_reg, val, thread->readTid()); 443 444 // Squash if we're not already in a state update mode. 445 if (!thread->trapPending && !thread->inSyscall) { 446 cpu->squashFromTC(thread->readTid()); 447 } 448} 449 450template <class Impl> 451void 452O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg, 453 const MiscReg &val) 454{ 455 cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid()); 456 457 // Squash if we're not already in a state update mode. 458 if (!thread->trapPending && !thread->inSyscall) { 459 cpu->squashFromTC(thread->readTid()); 460 } 461} 462 463#if !FULL_SYSTEM 464 465template <class Impl> 466TheISA::IntReg 467O3ThreadContext<Impl>::getSyscallArg(int i) 468{ 469 return cpu->getSyscallArg(i, thread->readTid()); 470} 471 472template <class Impl> 473void 474O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val) 475{ 476 cpu->setSyscallArg(i, val, thread->readTid()); 477} 478 479template <class Impl> 480void 481O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value) 482{ 483 cpu->setSyscallReturn(return_value, thread->readTid()); 484} 485 486#endif // FULL_SYSTEM 487
| 108} 109#endif 110 111template <class Impl> 112void 113O3ThreadContext<Impl>::activate(int delay) 114{ 115 DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", 116 getThreadNum()); 117 118 if (thread->status() == ThreadContext::Active) 119 return; 120 121#if FULL_SYSTEM 122 thread->lastActivate = curTick; 123#endif 124 125 if (thread->status() == ThreadContext::Unallocated) { 126 cpu->activateWhenReady(thread->readTid()); 127 return; 128 } 129 130 thread->setStatus(ThreadContext::Active); 131 132 // status() == Suspended 133 cpu->activateContext(thread->readTid(), delay); 134} 135 136template <class Impl> 137void 138O3ThreadContext<Impl>::suspend() 139{ 140 DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", 141 getThreadNum()); 142 143 if (thread->status() == ThreadContext::Suspended) 144 return; 145 146#if FULL_SYSTEM 147 thread->lastActivate = curTick; 148 thread->lastSuspend = curTick; 149#endif 150/* 151#if FULL_SYSTEM 152 // Don't change the status from active if there are pending interrupts 153 if (cpu->check_interrupts()) { 154 assert(status() == ThreadContext::Active); 155 return; 156 } 157#endif 158*/ 159 thread->setStatus(ThreadContext::Suspended); 160 cpu->suspendContext(thread->readTid()); 161} 162 163template <class Impl> 164void 165O3ThreadContext<Impl>::deallocate(int delay) 166{ 167 DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n", 168 getThreadNum(), delay); 169 170 if (thread->status() == ThreadContext::Unallocated) 171 return; 172 173 thread->setStatus(ThreadContext::Unallocated); 174 cpu->deallocateContext(thread->readTid(), true, delay); 175} 176 177template <class Impl> 178void 179O3ThreadContext<Impl>::halt() 180{ 181 DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", 182 getThreadNum()); 183 184 if (thread->status() == ThreadContext::Halted) 185 return; 186 187 thread->setStatus(ThreadContext::Halted); 188 cpu->haltContext(thread->readTid()); 189} 190 191template <class Impl> 192void 193O3ThreadContext<Impl>::regStats(const std::string &name) 194{ 195#if FULL_SYSTEM 196 thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system); 197 thread->kernelStats->regStats(name + ".kern"); 198#endif 199} 200 201template <class Impl> 202void 203O3ThreadContext<Impl>::serialize(std::ostream &os) 204{ 205#if FULL_SYSTEM 206 if (thread->kernelStats) 207 thread->kernelStats->serialize(os); 208#endif 209 210} 211 212template <class Impl> 213void 214O3ThreadContext<Impl>::unserialize(Checkpoint *cp, const std::string §ion) 215{ 216#if FULL_SYSTEM 217 if (thread->kernelStats) 218 thread->kernelStats->unserialize(cp, section); 219#endif 220 221} 222 223#if FULL_SYSTEM 224template <class Impl> 225Tick 226O3ThreadContext<Impl>::readLastActivate() 227{ 228 return thread->lastActivate; 229} 230 231template <class Impl> 232Tick 233O3ThreadContext<Impl>::readLastSuspend() 234{ 235 return thread->lastSuspend; 236} 237 238template <class Impl> 239void 240O3ThreadContext<Impl>::profileClear() 241{ 242 thread->profileClear(); 243} 244 245template <class Impl> 246void 247O3ThreadContext<Impl>::profileSample() 248{ 249 thread->profileSample(); 250} 251#endif 252 253template <class Impl> 254TheISA::MachInst 255O3ThreadContext<Impl>:: getInst() 256{ 257 return thread->getInst(); 258} 259 260template <class Impl> 261void 262O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc) 263{ 264 // This function will mess things up unless the ROB is empty and 265 // there are no instructions in the pipeline. 266 unsigned tid = thread->readTid(); 267 PhysRegIndex renamed_reg; 268 269 // First loop through the integer registers. 270 for (int i = 0; i < TheISA::NumIntRegs; ++i) { 271 renamed_reg = cpu->renameMap[tid].lookup(i); 272 273 DPRINTF(O3CPU, "Copying over register %i, had data %lli, " 274 "now has data %lli.\n", 275 renamed_reg, cpu->readIntReg(renamed_reg), 276 tc->readIntReg(i)); 277 278 cpu->setIntReg(renamed_reg, tc->readIntReg(i)); 279 } 280 281 // Then loop through the floating point registers. 282 for (int i = 0; i < TheISA::NumFloatRegs; ++i) { 283 renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag); 284 cpu->setFloatRegBits(renamed_reg, 285 tc->readFloatRegBits(i)); 286 } 287 288 // Copy the misc regs. 289 TheISA::copyMiscRegs(tc, this); 290 291 // Then finally set the PC and the next PC. 292 cpu->setPC(tc->readPC(), tid); 293 cpu->setNextPC(tc->readNextPC(), tid); 294#if !FULL_SYSTEM 295 this->thread->funcExeInst = tc->readFuncExeInst(); 296#endif 297} 298 299template <class Impl> 300void 301O3ThreadContext<Impl>::clearArchRegs() 302{} 303 304template <class Impl> 305uint64_t 306O3ThreadContext<Impl>::readIntReg(int reg_idx) 307{ 308 return cpu->readArchIntReg(reg_idx, thread->readTid()); 309} 310 311template <class Impl> 312TheISA::FloatReg 313O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width) 314{ 315 switch(width) { 316 case 32: 317 return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); 318 case 64: 319 return cpu->readArchFloatRegDouble(reg_idx, thread->readTid()); 320 default: 321 panic("Unsupported width!"); 322 return 0; 323 } 324} 325 326template <class Impl> 327TheISA::FloatReg 328O3ThreadContext<Impl>::readFloatReg(int reg_idx) 329{ 330 return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); 331} 332 333template <class Impl> 334TheISA::FloatRegBits 335O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width) 336{ 337 DPRINTF(Fault, "Reading floatint register through the TC!\n"); 338 return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); 339} 340 341template <class Impl> 342TheISA::FloatRegBits 343O3ThreadContext<Impl>::readFloatRegBits(int reg_idx) 344{ 345 return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); 346} 347 348template <class Impl> 349void 350O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val) 351{ 352 cpu->setArchIntReg(reg_idx, val, thread->readTid()); 353 354 // Squash if we're not already in a state update mode. 355 if (!thread->trapPending && !thread->inSyscall) { 356 cpu->squashFromTC(thread->readTid()); 357 } 358} 359 360template <class Impl> 361void 362O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width) 363{ 364 switch(width) { 365 case 32: 366 cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); 367 break; 368 case 64: 369 cpu->setArchFloatRegDouble(reg_idx, val, thread->readTid()); 370 break; 371 } 372 373 // Squash if we're not already in a state update mode. 374 if (!thread->trapPending && !thread->inSyscall) { 375 cpu->squashFromTC(thread->readTid()); 376 } 377} 378 379template <class Impl> 380void 381O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val) 382{ 383 cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); 384 385 if (!thread->trapPending && !thread->inSyscall) { 386 cpu->squashFromTC(thread->readTid()); 387 } 388} 389 390template <class Impl> 391void 392O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, 393 int width) 394{ 395 DPRINTF(Fault, "Setting floatint register through the TC!\n"); 396 cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); 397 398 // Squash if we're not already in a state update mode. 399 if (!thread->trapPending && !thread->inSyscall) { 400 cpu->squashFromTC(thread->readTid()); 401 } 402} 403 404template <class Impl> 405void 406O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) 407{ 408 cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); 409 410 // Squash if we're not already in a state update mode. 411 if (!thread->trapPending && !thread->inSyscall) { 412 cpu->squashFromTC(thread->readTid()); 413 } 414} 415 416template <class Impl> 417void 418O3ThreadContext<Impl>::setPC(uint64_t val) 419{ 420 cpu->setPC(val, thread->readTid()); 421 422 // Squash if we're not already in a state update mode. 423 if (!thread->trapPending && !thread->inSyscall) { 424 cpu->squashFromTC(thread->readTid()); 425 } 426} 427 428template <class Impl> 429void 430O3ThreadContext<Impl>::setNextPC(uint64_t val) 431{ 432 cpu->setNextPC(val, thread->readTid()); 433 434 // Squash if we're not already in a state update mode. 435 if (!thread->trapPending && !thread->inSyscall) { 436 cpu->squashFromTC(thread->readTid()); 437 } 438} 439 440template <class Impl> 441void 442O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val) 443{ 444 cpu->setMiscReg(misc_reg, val, thread->readTid()); 445 446 // Squash if we're not already in a state update mode. 447 if (!thread->trapPending && !thread->inSyscall) { 448 cpu->squashFromTC(thread->readTid()); 449 } 450} 451 452template <class Impl> 453void 454O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg, 455 const MiscReg &val) 456{ 457 cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid()); 458 459 // Squash if we're not already in a state update mode. 460 if (!thread->trapPending && !thread->inSyscall) { 461 cpu->squashFromTC(thread->readTid()); 462 } 463} 464 465#if !FULL_SYSTEM 466 467template <class Impl> 468TheISA::IntReg 469O3ThreadContext<Impl>::getSyscallArg(int i) 470{ 471 return cpu->getSyscallArg(i, thread->readTid()); 472} 473 474template <class Impl> 475void 476O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val) 477{ 478 cpu->setSyscallArg(i, val, thread->readTid()); 479} 480 481template <class Impl> 482void 483O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value) 484{ 485 cpu->setSyscallReturn(return_value, thread->readTid()); 486} 487 488#endif // FULL_SYSTEM 489
|