exec_context.hh revision 13652
1/* 2 * Copyright (c) 2011-2014, 2016-2017 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) 2002-2005 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: Steve Reinhardt 42 * Dave Greene 43 * Nathan Binkert 44 * Andrew Bardsley 45 */ 46 47/** 48 * @file 49 * 50 * ExecContext bears the exec_context interface for Minor. 51 */ 52 53#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__ 54#define __CPU_MINOR_EXEC_CONTEXT_HH__ 55 56#include "cpu/exec_context.hh" 57#include "cpu/minor/execute.hh" 58#include "cpu/minor/pipeline.hh" 59#include "cpu/base.hh" 60#include "cpu/simple_thread.hh" 61#include "mem/request.hh" 62#include "debug/MinorExecute.hh" 63 64namespace Minor 65{ 66 67/* Forward declaration of Execute */ 68class Execute; 69 70/** ExecContext bears the exec_context interface for Minor. This nicely 71 * separates that interface from other classes such as Pipeline, MinorCPU 72 * and DynMinorInst and makes it easier to see what state is accessed by it. 73 */ 74class ExecContext : public ::ExecContext 75{ 76 public: 77 MinorCPU &cpu; 78 79 /** ThreadState object, provides all the architectural state. */ 80 SimpleThread &thread; 81 82 /** The execute stage so we can peek at its contents. */ 83 Execute &execute; 84 85 /** Instruction for the benefit of memory operations and for PC */ 86 MinorDynInstPtr inst; 87 88 ExecContext ( 89 MinorCPU &cpu_, 90 SimpleThread &thread_, Execute &execute_, 91 MinorDynInstPtr inst_) : 92 cpu(cpu_), 93 thread(thread_), 94 execute(execute_), 95 inst(inst_) 96 { 97 DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); 98 pcState(inst->pc); 99 setPredicate(true); 100 thread.setIntReg(TheISA::ZeroReg, 0); 101#if THE_ISA == ALPHA_ISA 102 thread.setFloatReg(TheISA::ZeroReg, 0); 103#endif 104 } 105 106 Fault 107 initiateMemRead(Addr addr, unsigned int size, 108 Request::Flags flags) override 109 { 110 execute.getLSQ().pushRequest(inst, true /* load */, nullptr, 111 size, addr, flags, NULL, nullptr); 112 return NoFault; 113 } 114 115 Fault 116 writeMem(uint8_t *data, unsigned int size, Addr addr, 117 Request::Flags flags, uint64_t *res) override 118 { 119 execute.getLSQ().pushRequest(inst, false /* store */, data, 120 size, addr, flags, res, nullptr); 121 return NoFault; 122 } 123 124 Fault 125 initiateMemAMO(Addr addr, unsigned int size, Request::Flags flags, 126 AtomicOpFunctor *amo_op) override 127 { 128 // AMO requests are pushed through the store path 129 execute.getLSQ().pushRequest(inst, false /* amo */, nullptr, 130 size, addr, flags, nullptr, amo_op); 131 return NoFault; 132 } 133 134 RegVal 135 readIntRegOperand(const StaticInst *si, int idx) override 136 { 137 const RegId& reg = si->srcRegIdx(idx); 138 assert(reg.isIntReg()); 139 return thread.readIntReg(reg.index()); 140 } 141 142 RegVal 143 readFloatRegOperandBits(const StaticInst *si, int idx) override 144 { 145 const RegId& reg = si->srcRegIdx(idx); 146 assert(reg.isFloatReg()); 147 return thread.readFloatReg(reg.index()); 148 } 149 150 const TheISA::VecRegContainer & 151 readVecRegOperand(const StaticInst *si, int idx) const override 152 { 153 const RegId& reg = si->srcRegIdx(idx); 154 assert(reg.isVecReg()); 155 return thread.readVecReg(reg); 156 } 157 158 TheISA::VecRegContainer & 159 getWritableVecRegOperand(const StaticInst *si, int idx) override 160 { 161 const RegId& reg = si->destRegIdx(idx); 162 assert(reg.isVecReg()); 163 return thread.getWritableVecReg(reg); 164 } 165 166 TheISA::VecElem 167 readVecElemOperand(const StaticInst *si, int idx) const override 168 { 169 const RegId& reg = si->srcRegIdx(idx); 170 assert(reg.isVecElem()); 171 return thread.readVecElem(reg); 172 } 173 174 const TheISA::VecPredRegContainer& 175 readVecPredRegOperand(const StaticInst *si, int idx) const override 176 { 177 const RegId& reg = si->srcRegIdx(idx); 178 assert(reg.isVecPredReg()); 179 return thread.readVecPredReg(reg); 180 } 181 182 TheISA::VecPredRegContainer& 183 getWritableVecPredRegOperand(const StaticInst *si, int idx) override 184 { 185 const RegId& reg = si->destRegIdx(idx); 186 assert(reg.isVecPredReg()); 187 return thread.getWritableVecPredReg(reg); 188 } 189 190 void 191 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override 192 { 193 const RegId& reg = si->destRegIdx(idx); 194 assert(reg.isIntReg()); 195 thread.setIntReg(reg.index(), val); 196 } 197 198 void 199 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override 200 { 201 const RegId& reg = si->destRegIdx(idx); 202 assert(reg.isFloatReg()); 203 thread.setFloatReg(reg.index(), val); 204 } 205 206 void 207 setVecRegOperand(const StaticInst *si, int idx, 208 const TheISA::VecRegContainer& val) override 209 { 210 const RegId& reg = si->destRegIdx(idx); 211 assert(reg.isVecReg()); 212 thread.setVecReg(reg, val); 213 } 214 215 void 216 setVecPredRegOperand(const StaticInst *si, int idx, 217 const TheISA::VecPredRegContainer& val) override 218 { 219 const RegId& reg = si->destRegIdx(idx); 220 assert(reg.isVecPredReg()); 221 thread.setVecPredReg(reg, val); 222 } 223 224 /** Vector Register Lane Interfaces. */ 225 /** @{ */ 226 /** Reads source vector 8bit operand. */ 227 ConstVecLane8 228 readVec8BitLaneOperand(const StaticInst *si, int idx) const 229 override 230 { 231 const RegId& reg = si->srcRegIdx(idx); 232 assert(reg.isVecReg()); 233 return thread.readVec8BitLaneReg(reg); 234 } 235 236 /** Reads source vector 16bit operand. */ 237 ConstVecLane16 238 readVec16BitLaneOperand(const StaticInst *si, int idx) const 239 override 240 { 241 const RegId& reg = si->srcRegIdx(idx); 242 assert(reg.isVecReg()); 243 return thread.readVec16BitLaneReg(reg); 244 } 245 246 /** Reads source vector 32bit operand. */ 247 ConstVecLane32 248 readVec32BitLaneOperand(const StaticInst *si, int idx) const 249 override 250 { 251 const RegId& reg = si->srcRegIdx(idx); 252 assert(reg.isVecReg()); 253 return thread.readVec32BitLaneReg(reg); 254 } 255 256 /** Reads source vector 64bit operand. */ 257 ConstVecLane64 258 readVec64BitLaneOperand(const StaticInst *si, int idx) const 259 override 260 { 261 const RegId& reg = si->srcRegIdx(idx); 262 assert(reg.isVecReg()); 263 return thread.readVec64BitLaneReg(reg); 264 } 265 266 /** Write a lane of the destination vector operand. */ 267 template <typename LD> 268 void 269 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val) 270 { 271 const RegId& reg = si->destRegIdx(idx); 272 assert(reg.isVecReg()); 273 return thread.setVecLane(reg, val); 274 } 275 virtual void 276 setVecLaneOperand(const StaticInst *si, int idx, 277 const LaneData<LaneSize::Byte>& val) override 278 { 279 setVecLaneOperandT(si, idx, val); 280 } 281 virtual void 282 setVecLaneOperand(const StaticInst *si, int idx, 283 const LaneData<LaneSize::TwoByte>& val) override 284 { 285 setVecLaneOperandT(si, idx, val); 286 } 287 virtual void 288 setVecLaneOperand(const StaticInst *si, int idx, 289 const LaneData<LaneSize::FourByte>& val) override 290 { 291 setVecLaneOperandT(si, idx, val); 292 } 293 virtual void 294 setVecLaneOperand(const StaticInst *si, int idx, 295 const LaneData<LaneSize::EightByte>& val) override 296 { 297 setVecLaneOperandT(si, idx, val); 298 } 299 /** @} */ 300 301 void 302 setVecElemOperand(const StaticInst *si, int idx, 303 const TheISA::VecElem val) override 304 { 305 const RegId& reg = si->destRegIdx(idx); 306 assert(reg.isVecElem()); 307 thread.setVecElem(reg, val); 308 } 309 310 bool 311 readPredicate() const override 312 { 313 return thread.readPredicate(); 314 } 315 316 void 317 setPredicate(bool val) override 318 { 319 thread.setPredicate(val); 320 } 321 322 TheISA::PCState 323 pcState() const override 324 { 325 return thread.pcState(); 326 } 327 328 void 329 pcState(const TheISA::PCState &val) override 330 { 331 thread.pcState(val); 332 } 333 334 RegVal 335 readMiscRegNoEffect(int misc_reg) const 336 { 337 return thread.readMiscRegNoEffect(misc_reg); 338 } 339 340 RegVal 341 readMiscReg(int misc_reg) override 342 { 343 return thread.readMiscReg(misc_reg); 344 } 345 346 void 347 setMiscReg(int misc_reg, RegVal val) override 348 { 349 thread.setMiscReg(misc_reg, val); 350 } 351 352 RegVal 353 readMiscRegOperand(const StaticInst *si, int idx) override 354 { 355 const RegId& reg = si->srcRegIdx(idx); 356 assert(reg.isMiscReg()); 357 return thread.readMiscReg(reg.index()); 358 } 359 360 void 361 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override 362 { 363 const RegId& reg = si->destRegIdx(idx); 364 assert(reg.isMiscReg()); 365 return thread.setMiscReg(reg.index(), val); 366 } 367 368 Fault 369 hwrei() override 370 { 371#if THE_ISA == ALPHA_ISA 372 return thread.hwrei(); 373#else 374 return NoFault; 375#endif 376 } 377 378 bool 379 simPalCheck(int palFunc) override 380 { 381#if THE_ISA == ALPHA_ISA 382 return thread.simPalCheck(palFunc); 383#else 384 return false; 385#endif 386 } 387 388 void 389 syscall(int64_t callnum, Fault *fault) override 390 { 391 if (FullSystem) 392 panic("Syscall emulation isn't available in FS mode.\n"); 393 394 thread.syscall(callnum, fault); 395 } 396 397 ThreadContext *tcBase() override { return thread.getTC(); } 398 399 /* @todo, should make stCondFailures persistent somewhere */ 400 unsigned int readStCondFailures() const override { return 0; } 401 void setStCondFailures(unsigned int st_cond_failures) override {} 402 403 ContextID contextId() { return thread.contextId(); } 404 /* ISA-specific (or at least currently ISA singleton) functions */ 405 406 /* X86: TLB twiddling */ 407 void 408 demapPage(Addr vaddr, uint64_t asn) override 409 { 410 thread.getITBPtr()->demapPage(vaddr, asn); 411 thread.getDTBPtr()->demapPage(vaddr, asn); 412 } 413 414 RegVal 415 readCCRegOperand(const StaticInst *si, int idx) override 416 { 417 const RegId& reg = si->srcRegIdx(idx); 418 assert(reg.isCCReg()); 419 return thread.readCCReg(reg.index()); 420 } 421 422 void 423 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override 424 { 425 const RegId& reg = si->destRegIdx(idx); 426 assert(reg.isCCReg()); 427 thread.setCCReg(reg.index(), val); 428 } 429 430 void 431 demapInstPage(Addr vaddr, uint64_t asn) 432 { 433 thread.getITBPtr()->demapPage(vaddr, asn); 434 } 435 436 void 437 demapDataPage(Addr vaddr, uint64_t asn) 438 { 439 thread.getDTBPtr()->demapPage(vaddr, asn); 440 } 441 442 BaseCPU *getCpuPtr() { return &cpu; } 443 444 /* MIPS: other thread register reading/writing */ 445 RegVal 446 readRegOtherThread(const RegId ®, ThreadID tid=InvalidThreadID) 447 { 448 SimpleThread *other_thread = (tid == InvalidThreadID 449 ? &thread : cpu.threads[tid]); 450 451 switch (reg.classValue()) { 452 case IntRegClass: 453 return other_thread->readIntReg(reg.index()); 454 break; 455 case FloatRegClass: 456 return other_thread->readFloatReg(reg.index()); 457 break; 458 case MiscRegClass: 459 return other_thread->readMiscReg(reg.index()); 460 default: 461 panic("Unexpected reg class! (%s)", 462 reg.className()); 463 return 0; 464 } 465 } 466 467 void 468 setRegOtherThread(const RegId ®, RegVal val, 469 ThreadID tid=InvalidThreadID) 470 { 471 SimpleThread *other_thread = (tid == InvalidThreadID 472 ? &thread : cpu.threads[tid]); 473 474 switch (reg.classValue()) { 475 case IntRegClass: 476 return other_thread->setIntReg(reg.index(), val); 477 break; 478 case FloatRegClass: 479 return other_thread->setFloatReg(reg.index(), val); 480 break; 481 case MiscRegClass: 482 return other_thread->setMiscReg(reg.index(), val); 483 default: 484 panic("Unexpected reg class! (%s)", 485 reg.className()); 486 } 487 } 488 489 public: 490 // monitor/mwait funtions 491 void armMonitor(Addr address) override 492 { getCpuPtr()->armMonitor(inst->id.threadId, address); } 493 494 bool mwait(PacketPtr pkt) override 495 { return getCpuPtr()->mwait(inst->id.threadId, pkt); } 496 497 void mwaitAtomic(ThreadContext *tc) override 498 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); } 499 500 AddressMonitor *getAddrMonitor() override 501 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); } 502}; 503 504} 505 506#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ 507