exec_context.hh revision 13953
1/* 2 * Copyright (c) 2011-2014, 2016-2018 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 bool 323 readMemAccPredicate() const override 324 { 325 return thread.readMemAccPredicate(); 326 } 327 328 void 329 setMemAccPredicate(bool val) override 330 { 331 thread.setMemAccPredicate(val); 332 } 333 334 TheISA::PCState 335 pcState() const override 336 { 337 return thread.pcState(); 338 } 339 340 void 341 pcState(const TheISA::PCState &val) override 342 { 343 thread.pcState(val); 344 } 345 346 RegVal 347 readMiscRegNoEffect(int misc_reg) const 348 { 349 return thread.readMiscRegNoEffect(misc_reg); 350 } 351 352 RegVal 353 readMiscReg(int misc_reg) override 354 { 355 return thread.readMiscReg(misc_reg); 356 } 357 358 void 359 setMiscReg(int misc_reg, RegVal val) override 360 { 361 thread.setMiscReg(misc_reg, val); 362 } 363 364 RegVal 365 readMiscRegOperand(const StaticInst *si, int idx) override 366 { 367 const RegId& reg = si->srcRegIdx(idx); 368 assert(reg.isMiscReg()); 369 return thread.readMiscReg(reg.index()); 370 } 371 372 void 373 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override 374 { 375 const RegId& reg = si->destRegIdx(idx); 376 assert(reg.isMiscReg()); 377 return thread.setMiscReg(reg.index(), val); 378 } 379 380 void 381 syscall(int64_t callnum, Fault *fault) override 382 { 383 if (FullSystem) 384 panic("Syscall emulation isn't available in FS mode.\n"); 385 386 thread.syscall(callnum, fault); 387 } 388 389 ThreadContext *tcBase() override { return thread.getTC(); } 390 391 /* @todo, should make stCondFailures persistent somewhere */ 392 unsigned int readStCondFailures() const override { return 0; } 393 void setStCondFailures(unsigned int st_cond_failures) override {} 394 395 ContextID contextId() { return thread.contextId(); } 396 /* ISA-specific (or at least currently ISA singleton) functions */ 397 398 /* X86: TLB twiddling */ 399 void 400 demapPage(Addr vaddr, uint64_t asn) override 401 { 402 thread.getITBPtr()->demapPage(vaddr, asn); 403 thread.getDTBPtr()->demapPage(vaddr, asn); 404 } 405 406 RegVal 407 readCCRegOperand(const StaticInst *si, int idx) override 408 { 409 const RegId& reg = si->srcRegIdx(idx); 410 assert(reg.isCCReg()); 411 return thread.readCCReg(reg.index()); 412 } 413 414 void 415 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override 416 { 417 const RegId& reg = si->destRegIdx(idx); 418 assert(reg.isCCReg()); 419 thread.setCCReg(reg.index(), val); 420 } 421 422 void 423 demapInstPage(Addr vaddr, uint64_t asn) 424 { 425 thread.getITBPtr()->demapPage(vaddr, asn); 426 } 427 428 void 429 demapDataPage(Addr vaddr, uint64_t asn) 430 { 431 thread.getDTBPtr()->demapPage(vaddr, asn); 432 } 433 434 BaseCPU *getCpuPtr() { return &cpu; } 435 436 public: 437 // monitor/mwait funtions 438 void armMonitor(Addr address) override 439 { getCpuPtr()->armMonitor(inst->id.threadId, address); } 440 441 bool mwait(PacketPtr pkt) override 442 { return getCpuPtr()->mwait(inst->id.threadId, pkt); } 443 444 void mwaitAtomic(ThreadContext *tc) override 445 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); } 446 447 AddressMonitor *getAddrMonitor() override 448 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); } 449}; 450 451} 452 453#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ 454