thread_context_impl.hh revision 5803
17584SAli.Saidi@arm.com/* 27584SAli.Saidi@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 37584SAli.Saidi@arm.com * All rights reserved. 47584SAli.Saidi@arm.com * 57584SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 67584SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 77584SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 87584SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 97584SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 107584SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 117584SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 127584SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 137584SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 147584SAli.Saidi@arm.com * this software without specific prior written permission. 157584SAli.Saidi@arm.com * 167584SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177584SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187584SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197584SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207584SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217584SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227584SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237584SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247584SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257584SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267584SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277584SAli.Saidi@arm.com * 287584SAli.Saidi@arm.com * Authors: Kevin Lim 297584SAli.Saidi@arm.com * Korey Sewell 307584SAli.Saidi@arm.com */ 317584SAli.Saidi@arm.com 327584SAli.Saidi@arm.com#include "arch/regfile.hh" 337584SAli.Saidi@arm.com#include "cpu/o3/thread_context.hh" 347584SAli.Saidi@arm.com#include "cpu/quiesce_event.hh" 357584SAli.Saidi@arm.com 367584SAli.Saidi@arm.com#if FULL_SYSTEM 377584SAli.Saidi@arm.comtemplate <class Impl> 387584SAli.Saidi@arm.comVirtualPort * 397584SAli.Saidi@arm.comO3ThreadContext<Impl>::getVirtPort() 407584SAli.Saidi@arm.com{ 417584SAli.Saidi@arm.com return thread->getVirtPort(); 428245Snate@binkert.org} 438245Snate@binkert.org 447584SAli.Saidi@arm.comtemplate <class Impl> 457584SAli.Saidi@arm.comvoid 467584SAli.Saidi@arm.comO3ThreadContext<Impl>::dumpFuncProfile() 477584SAli.Saidi@arm.com{ 487584SAli.Saidi@arm.com thread->dumpFuncProfile(); 497587SAli.Saidi@arm.com} 507587SAli.Saidi@arm.com#endif 517584SAli.Saidi@arm.com 527584SAli.Saidi@arm.comtemplate <class Impl> 537584SAli.Saidi@arm.comvoid 547584SAli.Saidi@arm.comO3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context) 557584SAli.Saidi@arm.com{ 567584SAli.Saidi@arm.com // some things should already be set up 577584SAli.Saidi@arm.com assert(getSystemPtr() == old_context->getSystemPtr()); 587584SAli.Saidi@arm.com#if !FULL_SYSTEM 597584SAli.Saidi@arm.com assert(getProcessPtr() == old_context->getProcessPtr()); 607584SAli.Saidi@arm.com#endif 617584SAli.Saidi@arm.com 627584SAli.Saidi@arm.com // copy over functional state 637584SAli.Saidi@arm.com setStatus(old_context->status()); 647584SAli.Saidi@arm.com copyArchRegs(old_context); 657584SAli.Saidi@arm.com setContextId(old_context->contextId()); 667584SAli.Saidi@arm.com setThreadId(old_context->threadId()); 677584SAli.Saidi@arm.com 687584SAli.Saidi@arm.com#if !FULL_SYSTEM 697584SAli.Saidi@arm.com thread->funcExeInst = old_context->readFuncExeInst(); 707584SAli.Saidi@arm.com#else 717584SAli.Saidi@arm.com EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent(); 727584SAli.Saidi@arm.com if (other_quiesce) { 737584SAli.Saidi@arm.com // Point the quiesce event's TC at this TC so that it wakes up 747584SAli.Saidi@arm.com // the proper CPU. 757584SAli.Saidi@arm.com other_quiesce->tc = this; 767584SAli.Saidi@arm.com } 777584SAli.Saidi@arm.com if (thread->quiesceEvent) { 787587SAli.Saidi@arm.com thread->quiesceEvent->tc = this; 797584SAli.Saidi@arm.com } 807584SAli.Saidi@arm.com 817584SAli.Saidi@arm.com // Transfer kernel stats from one CPU to the other. 827584SAli.Saidi@arm.com thread->kernelStats = old_context->getKernelStats(); 837584SAli.Saidi@arm.com// storeCondFailures = 0; 847584SAli.Saidi@arm.com cpu->lockFlag = false; 857584SAli.Saidi@arm.com#endif 867584SAli.Saidi@arm.com 877584SAli.Saidi@arm.com old_context->setStatus(ThreadContext::Unallocated); 887584SAli.Saidi@arm.com 897584SAli.Saidi@arm.com thread->inSyscall = false; 907584SAli.Saidi@arm.com thread->trapPending = false; 917584SAli.Saidi@arm.com} 927584SAli.Saidi@arm.com 937584SAli.Saidi@arm.comtemplate <class Impl> 947584SAli.Saidi@arm.comvoid 957584SAli.Saidi@arm.comO3ThreadContext<Impl>::activate(int delay) 967823Ssteve.reinhardt@amd.com{ 977584SAli.Saidi@arm.com DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", 987584SAli.Saidi@arm.com threadId()); 997584SAli.Saidi@arm.com 1007584SAli.Saidi@arm.com if (thread->status() == ThreadContext::Active) 1017584SAli.Saidi@arm.com return; 1027584SAli.Saidi@arm.com 1037584SAli.Saidi@arm.com#if FULL_SYSTEM 1047584SAli.Saidi@arm.com thread->lastActivate = curTick; 1057584SAli.Saidi@arm.com#endif 1067584SAli.Saidi@arm.com 1077584SAli.Saidi@arm.com if (thread->status() == ThreadContext::Unallocated) { 1087584SAli.Saidi@arm.com cpu->activateWhenReady(thread->threadId()); 1097584SAli.Saidi@arm.com return; 1107584SAli.Saidi@arm.com } 1117584SAli.Saidi@arm.com 1127584SAli.Saidi@arm.com thread->setStatus(ThreadContext::Active); 1137584SAli.Saidi@arm.com 1147584SAli.Saidi@arm.com // status() == Suspended 1157584SAli.Saidi@arm.com cpu->activateContext(thread->threadId(), delay); 1167584SAli.Saidi@arm.com} 1178524SAli.Saidi@ARM.com 1187584SAli.Saidi@arm.comtemplate <class Impl> 1197584SAli.Saidi@arm.comvoid 1207584SAli.Saidi@arm.comO3ThreadContext<Impl>::suspend(int delay) 1217584SAli.Saidi@arm.com{ 1227584SAli.Saidi@arm.com DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", 1237584SAli.Saidi@arm.com threadId()); 1247584SAli.Saidi@arm.com 1257584SAli.Saidi@arm.com if (thread->status() == ThreadContext::Suspended) 1267584SAli.Saidi@arm.com return; 1277584SAli.Saidi@arm.com 1287584SAli.Saidi@arm.com#if FULL_SYSTEM 1297584SAli.Saidi@arm.com thread->lastActivate = curTick; 1307584SAli.Saidi@arm.com thread->lastSuspend = curTick; 1317584SAli.Saidi@arm.com#endif 1327584SAli.Saidi@arm.com/* 1337587SAli.Saidi@arm.com#if FULL_SYSTEM 1347584SAli.Saidi@arm.com // Don't change the status from active if there are pending interrupts 1357584SAli.Saidi@arm.com if (cpu->checkInterrupts()) { 1367584SAli.Saidi@arm.com assert(status() == ThreadContext::Active); 1377584SAli.Saidi@arm.com return; 1387584SAli.Saidi@arm.com } 1397584SAli.Saidi@arm.com#endif 1407584SAli.Saidi@arm.com*/ 1417584SAli.Saidi@arm.com thread->setStatus(ThreadContext::Suspended); 1428524SAli.Saidi@ARM.com cpu->suspendContext(thread->threadId()); 1437584SAli.Saidi@arm.com} 1447584SAli.Saidi@arm.com 1457584SAli.Saidi@arm.comtemplate <class Impl> 1467584SAli.Saidi@arm.comvoid 1477584SAli.Saidi@arm.comO3ThreadContext<Impl>::deallocate(int delay) 1487584SAli.Saidi@arm.com{ 1497584SAli.Saidi@arm.com DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n", 1507584SAli.Saidi@arm.com threadId(), delay); 1517584SAli.Saidi@arm.com 1527584SAli.Saidi@arm.com if (thread->status() == ThreadContext::Unallocated) 1537584SAli.Saidi@arm.com return; 1547584SAli.Saidi@arm.com 1557584SAli.Saidi@arm.com thread->setStatus(ThreadContext::Unallocated); 1567584SAli.Saidi@arm.com cpu->deallocateContext(thread->threadId(), true, delay); 1577584SAli.Saidi@arm.com} 1587584SAli.Saidi@arm.com 1597584SAli.Saidi@arm.comtemplate <class Impl> 1607584SAli.Saidi@arm.comvoid 1617584SAli.Saidi@arm.comO3ThreadContext<Impl>::halt(int delay) 1627584SAli.Saidi@arm.com{ 1637584SAli.Saidi@arm.com DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", 1647584SAli.Saidi@arm.com threadId()); 1657584SAli.Saidi@arm.com 1667584SAli.Saidi@arm.com if (thread->status() == ThreadContext::Halted) 1677584SAli.Saidi@arm.com return; 1687584SAli.Saidi@arm.com 1697584SAli.Saidi@arm.com thread->setStatus(ThreadContext::Halted); 1707584SAli.Saidi@arm.com cpu->haltContext(thread->threadId()); 1717584SAli.Saidi@arm.com} 1727584SAli.Saidi@arm.com 1737584SAli.Saidi@arm.comtemplate <class Impl> 1747584SAli.Saidi@arm.comvoid 1757584SAli.Saidi@arm.comO3ThreadContext<Impl>::regStats(const std::string &name) 1767584SAli.Saidi@arm.com{ 1777584SAli.Saidi@arm.com#if FULL_SYSTEM 1787584SAli.Saidi@arm.com thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system); 1797584SAli.Saidi@arm.com thread->kernelStats->regStats(name + ".kern"); 1807584SAli.Saidi@arm.com#endif 1817584SAli.Saidi@arm.com} 1827943SAli.Saidi@ARM.com 1837584SAli.Saidi@arm.comtemplate <class Impl> 1847943SAli.Saidi@ARM.comvoid 1857943SAli.Saidi@ARM.comO3ThreadContext<Impl>::serialize(std::ostream &os) 1867584SAli.Saidi@arm.com{ 1877584SAli.Saidi@arm.com#if FULL_SYSTEM 1887584SAli.Saidi@arm.com if (thread->kernelStats) 1897584SAli.Saidi@arm.com thread->kernelStats->serialize(os); 1907584SAli.Saidi@arm.com#endif 1917584SAli.Saidi@arm.com 1927823Ssteve.reinhardt@amd.com} 1937823Ssteve.reinhardt@amd.com 1947584SAli.Saidi@arm.comtemplate <class Impl> 1957584SAli.Saidi@arm.comvoid 1967584SAli.Saidi@arm.comO3ThreadContext<Impl>::unserialize(Checkpoint *cp, const std::string §ion) 1977584SAli.Saidi@arm.com{ 1987584SAli.Saidi@arm.com#if FULL_SYSTEM 1997584SAli.Saidi@arm.com if (thread->kernelStats) 2007584SAli.Saidi@arm.com thread->kernelStats->unserialize(cp, section); 2017584SAli.Saidi@arm.com#endif 2027584SAli.Saidi@arm.com 2037584SAli.Saidi@arm.com} 2047584SAli.Saidi@arm.com 2057584SAli.Saidi@arm.com#if FULL_SYSTEM 2067584SAli.Saidi@arm.comtemplate <class Impl> 2077584SAli.Saidi@arm.comTick 2087584SAli.Saidi@arm.comO3ThreadContext<Impl>::readLastActivate() 2097584SAli.Saidi@arm.com{ 2107584SAli.Saidi@arm.com return thread->lastActivate; 2117584SAli.Saidi@arm.com} 2127584SAli.Saidi@arm.com 2137584SAli.Saidi@arm.comtemplate <class Impl> 2147584SAli.Saidi@arm.comTick 2157584SAli.Saidi@arm.comO3ThreadContext<Impl>::readLastSuspend() 2167584SAli.Saidi@arm.com{ 2177584SAli.Saidi@arm.com return thread->lastSuspend; 2187584SAli.Saidi@arm.com} 2197584SAli.Saidi@arm.com 2207584SAli.Saidi@arm.comtemplate <class Impl> 2217584SAli.Saidi@arm.comvoid 2227584SAli.Saidi@arm.comO3ThreadContext<Impl>::profileClear() 2237733SAli.Saidi@ARM.com{ 2247733SAli.Saidi@ARM.com thread->profileClear(); 2257733SAli.Saidi@ARM.com} 2267733SAli.Saidi@ARM.com 2277733SAli.Saidi@ARM.comtemplate <class Impl> 2287733SAli.Saidi@ARM.comvoid 2297733SAli.Saidi@ARM.comO3ThreadContext<Impl>::profileSample() 2307733SAli.Saidi@ARM.com{ 2317733SAli.Saidi@ARM.com thread->profileSample(); 2327733SAli.Saidi@ARM.com} 2337733SAli.Saidi@ARM.com#endif 2347733SAli.Saidi@ARM.com 2357733SAli.Saidi@ARM.comtemplate <class Impl> 2367733SAli.Saidi@ARM.comTheISA::MachInst 2377733SAli.Saidi@ARM.comO3ThreadContext<Impl>:: getInst() 2387733SAli.Saidi@ARM.com{ 2397733SAli.Saidi@ARM.com return thread->getInst(); 2407733SAli.Saidi@ARM.com} 2417733SAli.Saidi@ARM.com 2427733SAli.Saidi@ARM.comtemplate <class Impl> 2437733SAli.Saidi@ARM.comvoid 2447733SAli.Saidi@ARM.comO3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc) 2457733SAli.Saidi@ARM.com{ 2467733SAli.Saidi@ARM.com // This function will mess things up unless the ROB is empty and 2477733SAli.Saidi@ARM.com // there are no instructions in the pipeline. 2487733SAli.Saidi@ARM.com unsigned tid = thread->threadId(); 2497733SAli.Saidi@ARM.com PhysRegIndex renamed_reg; 2507733SAli.Saidi@ARM.com 2517733SAli.Saidi@ARM.com // First loop through the integer registers. 2527733SAli.Saidi@ARM.com for (int i = 0; i < TheISA::NumIntRegs; ++i) { 2537733SAli.Saidi@ARM.com renamed_reg = cpu->renameMap[tid].lookup(i); 2547733SAli.Saidi@ARM.com 2557733SAli.Saidi@ARM.com DPRINTF(O3CPU, "Copying over register %i, had data %lli, " 2567733SAli.Saidi@ARM.com "now has data %lli.\n", 2577733SAli.Saidi@ARM.com renamed_reg, cpu->readIntReg(renamed_reg), 2587733SAli.Saidi@ARM.com tc->readIntReg(i)); 2597733SAli.Saidi@ARM.com 2607733SAli.Saidi@ARM.com cpu->setIntReg(renamed_reg, tc->readIntReg(i)); 2617733SAli.Saidi@ARM.com } 2627733SAli.Saidi@ARM.com 2637733SAli.Saidi@ARM.com // Then loop through the floating point registers. 2647733SAli.Saidi@ARM.com for (int i = 0; i < TheISA::NumFloatRegs; ++i) { 2657733SAli.Saidi@ARM.com renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag); 2667733SAli.Saidi@ARM.com cpu->setFloatRegBits(renamed_reg, 2677733SAli.Saidi@ARM.com tc->readFloatRegBits(i)); 2687733SAli.Saidi@ARM.com } 2697733SAli.Saidi@ARM.com 2707733SAli.Saidi@ARM.com // Copy the misc regs. 2717733SAli.Saidi@ARM.com TheISA::copyMiscRegs(tc, this); 2727733SAli.Saidi@ARM.com 2737733SAli.Saidi@ARM.com // Then finally set the PC, the next PC, the nextNPC, the micropc, and the 2747584SAli.Saidi@arm.com // next micropc. 2757584SAli.Saidi@arm.com cpu->setPC(tc->readPC(), tid); 2767584SAli.Saidi@arm.com cpu->setNextPC(tc->readNextPC(), tid); 2777584SAli.Saidi@arm.com cpu->setNextNPC(tc->readNextNPC(), tid); 2787733SAli.Saidi@ARM.com cpu->setMicroPC(tc->readMicroPC(), tid); 2797733SAli.Saidi@ARM.com cpu->setNextMicroPC(tc->readNextMicroPC(), tid); 2807733SAli.Saidi@ARM.com#if !FULL_SYSTEM 2817733SAli.Saidi@ARM.com this->thread->funcExeInst = tc->readFuncExeInst(); 2827584SAli.Saidi@arm.com#endif 2837584SAli.Saidi@arm.com} 2847584SAli.Saidi@arm.com 2857584SAli.Saidi@arm.comtemplate <class Impl> 2867584SAli.Saidi@arm.comvoid 2877733SAli.Saidi@ARM.comO3ThreadContext<Impl>::clearArchRegs() 2887733SAli.Saidi@ARM.com{} 2897584SAli.Saidi@arm.com 2907584SAli.Saidi@arm.comtemplate <class Impl> 2917584SAli.Saidi@arm.comuint64_t 2927584SAli.Saidi@arm.comO3ThreadContext<Impl>::readIntReg(int reg_idx) 2937584SAli.Saidi@arm.com{ 2947584SAli.Saidi@arm.com reg_idx = TheISA::flattenIntIndex(this, reg_idx); 2957584SAli.Saidi@arm.com return cpu->readArchIntReg(reg_idx, thread->threadId()); 296} 297 298template <class Impl> 299TheISA::FloatReg 300O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width) 301{ 302 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 303 switch(width) { 304 case 32: 305 return cpu->readArchFloatRegSingle(reg_idx, thread->threadId()); 306 case 64: 307 return cpu->readArchFloatRegDouble(reg_idx, thread->threadId()); 308 default: 309 panic("Unsupported width!"); 310 return 0; 311 } 312} 313 314template <class Impl> 315TheISA::FloatReg 316O3ThreadContext<Impl>::readFloatReg(int reg_idx) 317{ 318 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 319 return cpu->readArchFloatRegSingle(reg_idx, thread->threadId()); 320} 321 322template <class Impl> 323TheISA::FloatRegBits 324O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width) 325{ 326 DPRINTF(Fault, "Reading floatint register through the TC!\n"); 327 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 328 return cpu->readArchFloatRegInt(reg_idx, thread->threadId()); 329} 330 331template <class Impl> 332TheISA::FloatRegBits 333O3ThreadContext<Impl>::readFloatRegBits(int reg_idx) 334{ 335 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 336 return cpu->readArchFloatRegInt(reg_idx, thread->threadId()); 337} 338 339template <class Impl> 340void 341O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val) 342{ 343 reg_idx = TheISA::flattenIntIndex(this, reg_idx); 344 cpu->setArchIntReg(reg_idx, val, thread->threadId()); 345 346 // Squash if we're not already in a state update mode. 347 if (!thread->trapPending && !thread->inSyscall) { 348 cpu->squashFromTC(thread->threadId()); 349 } 350} 351 352template <class Impl> 353void 354O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width) 355{ 356 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 357 switch(width) { 358 case 32: 359 cpu->setArchFloatRegSingle(reg_idx, val, thread->threadId()); 360 break; 361 case 64: 362 cpu->setArchFloatRegDouble(reg_idx, val, thread->threadId()); 363 break; 364 } 365 366 // Squash if we're not already in a state update mode. 367 if (!thread->trapPending && !thread->inSyscall) { 368 cpu->squashFromTC(thread->threadId()); 369 } 370} 371 372template <class Impl> 373void 374O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val) 375{ 376 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 377 cpu->setArchFloatRegSingle(reg_idx, val, thread->threadId()); 378 379 if (!thread->trapPending && !thread->inSyscall) { 380 cpu->squashFromTC(thread->threadId()); 381 } 382} 383 384template <class Impl> 385void 386O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, 387 int width) 388{ 389 DPRINTF(Fault, "Setting floatint register through the TC!\n"); 390 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 391 cpu->setArchFloatRegInt(reg_idx, val, thread->threadId()); 392 393 // Squash if we're not already in a state update mode. 394 if (!thread->trapPending && !thread->inSyscall) { 395 cpu->squashFromTC(thread->threadId()); 396 } 397} 398 399template <class Impl> 400void 401O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) 402{ 403 reg_idx = TheISA::flattenFloatIndex(this, reg_idx); 404 cpu->setArchFloatRegInt(reg_idx, val, thread->threadId()); 405 406 // Squash if we're not already in a state update mode. 407 if (!thread->trapPending && !thread->inSyscall) { 408 cpu->squashFromTC(thread->threadId()); 409 } 410} 411 412template <class Impl> 413void 414O3ThreadContext<Impl>::setPC(uint64_t val) 415{ 416 cpu->setPC(val, thread->threadId()); 417 418 // Squash if we're not already in a state update mode. 419 if (!thread->trapPending && !thread->inSyscall) { 420 cpu->squashFromTC(thread->threadId()); 421 } 422} 423 424template <class Impl> 425void 426O3ThreadContext<Impl>::setNextPC(uint64_t val) 427{ 428 cpu->setNextPC(val, thread->threadId()); 429 430 // Squash if we're not already in a state update mode. 431 if (!thread->trapPending && !thread->inSyscall) { 432 cpu->squashFromTC(thread->threadId()); 433 } 434} 435 436template <class Impl> 437void 438O3ThreadContext<Impl>::setMicroPC(uint64_t val) 439{ 440 cpu->setMicroPC(val, thread->threadId()); 441 442 // Squash if we're not already in a state update mode. 443 if (!thread->trapPending && !thread->inSyscall) { 444 cpu->squashFromTC(thread->threadId()); 445 } 446} 447 448template <class Impl> 449void 450O3ThreadContext<Impl>::setNextMicroPC(uint64_t val) 451{ 452 cpu->setNextMicroPC(val, thread->threadId()); 453 454 // Squash if we're not already in a state update mode. 455 if (!thread->trapPending && !thread->inSyscall) { 456 cpu->squashFromTC(thread->threadId()); 457 } 458} 459 460template <class Impl> 461void 462O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val) 463{ 464 cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId()); 465 466 // Squash if we're not already in a state update mode. 467 if (!thread->trapPending && !thread->inSyscall) { 468 cpu->squashFromTC(thread->threadId()); 469 } 470} 471 472template <class Impl> 473void 474O3ThreadContext<Impl>::setMiscReg(int misc_reg, 475 const MiscReg &val) 476{ 477 cpu->setMiscReg(misc_reg, val, thread->threadId()); 478 479 // Squash if we're not already in a state update mode. 480 if (!thread->trapPending && !thread->inSyscall) { 481 cpu->squashFromTC(thread->threadId()); 482 } 483} 484 485#if !FULL_SYSTEM 486 487template <class Impl> 488TheISA::IntReg 489O3ThreadContext<Impl>::getSyscallArg(int i) 490{ 491 return cpu->getSyscallArg(i, thread->threadId()); 492} 493 494template <class Impl> 495void 496O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val) 497{ 498 cpu->setSyscallArg(i, val, thread->threadId()); 499} 500 501template <class Impl> 502void 503O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value) 504{ 505 cpu->setSyscallReturn(return_value, thread->threadId()); 506} 507 508#endif // FULL_SYSTEM 509 510