exec_context.hh revision 10259
1/* 2 * Copyright (c) 2011-2014 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/minor/execute.hh" 57#include "cpu/minor/pipeline.hh" 58#include "cpu/base.hh" 59#include "cpu/simple_thread.hh" 60#include "debug/MinorExecute.hh" 61 62namespace Minor 63{ 64 65/* Forward declaration of Execute */ 66class Execute; 67 68/** ExecContext bears the exec_context interface for Minor. This nicely 69 * separates that interface from other classes such as Pipeline, MinorCPU 70 * and DynMinorInst and makes it easier to see what state is accessed by it. 71 */ 72class ExecContext 73{ 74 public: 75 MinorCPU &cpu; 76 77 /** ThreadState object, provides all the architectural state. */ 78 SimpleThread &thread; 79 80 /** The execute stage so we can peek at its contents. */ 81 Execute &execute; 82 83 /** Instruction for the benefit of memory operations and for PC */ 84 MinorDynInstPtr inst; 85 86 ExecContext ( 87 MinorCPU &cpu_, 88 SimpleThread &thread_, Execute &execute_, 89 MinorDynInstPtr inst_) : 90 cpu(cpu_), 91 thread(thread_), 92 execute(execute_), 93 inst(inst_) 94 { 95 DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); 96 pcState(inst->pc); 97 setPredicate(true); 98 thread.setIntReg(TheISA::ZeroReg, 0); 99#if THE_ISA == ALPHA_ISA 100 thread.setFloatReg(TheISA::ZeroReg, 0.0); 101#endif 102 } 103 104 Fault 105 readMem(Addr addr, uint8_t *data, unsigned int size, 106 unsigned int flags) 107 { 108 execute.getLSQ().pushRequest(inst, true /* load */, data, 109 size, addr, flags, NULL); 110 return NoFault; 111 } 112 113 Fault 114 writeMem(uint8_t *data, unsigned int size, Addr addr, 115 unsigned int flags, uint64_t *res) 116 { 117 execute.getLSQ().pushRequest(inst, false /* store */, data, 118 size, addr, flags, res); 119 return NoFault; 120 } 121 122 uint64_t 123 readIntRegOperand(const StaticInst *si, int idx) 124 { 125 return thread.readIntReg(si->srcRegIdx(idx)); 126 } 127 128 TheISA::FloatReg 129 readFloatRegOperand(const StaticInst *si, int idx) 130 { 131 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 132 return thread.readFloatReg(reg_idx); 133 } 134 135 TheISA::FloatRegBits 136 readFloatRegOperandBits(const StaticInst *si, int idx) 137 { 138 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 139 return thread.readFloatRegBits(reg_idx); 140 } 141 142 void 143 setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 144 { 145 thread.setIntReg(si->destRegIdx(idx), val); 146 } 147 148 void 149 setFloatRegOperand(const StaticInst *si, int idx, 150 TheISA::FloatReg val) 151 { 152 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 153 thread.setFloatReg(reg_idx, val); 154 } 155 156 void 157 setFloatRegOperandBits(const StaticInst *si, int idx, 158 TheISA::FloatRegBits val) 159 { 160 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 161 thread.setFloatRegBits(reg_idx, val); 162 } 163 164 bool 165 readPredicate() 166 { 167 return thread.readPredicate(); 168 } 169 170 void 171 setPredicate(bool val) 172 { 173 thread.setPredicate(val); 174 } 175 176 TheISA::PCState 177 pcState() 178 { 179 return thread.pcState(); 180 } 181 182 void 183 pcState(const TheISA::PCState &val) 184 { 185 thread.pcState(val); 186 } 187 188 TheISA::MiscReg 189 readMiscRegNoEffect(int misc_reg) 190 { 191 return thread.readMiscRegNoEffect(misc_reg); 192 } 193 194 TheISA::MiscReg 195 readMiscReg(int misc_reg) 196 { 197 return thread.readMiscReg(misc_reg); 198 } 199 200 void 201 setMiscReg(int misc_reg, const TheISA::MiscReg &val) 202 { 203 thread.setMiscReg(misc_reg, val); 204 } 205 206 TheISA::MiscReg 207 readMiscRegOperand(const StaticInst *si, int idx) 208 { 209 int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; 210 return thread.readMiscReg(reg_idx); 211 } 212 213 void 214 setMiscRegOperand(const StaticInst *si, int idx, 215 const TheISA::MiscReg &val) 216 { 217 int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; 218 return thread.setMiscReg(reg_idx, val); 219 } 220 221 Fault 222 hwrei() 223 { 224#if THE_ISA == ALPHA_ISA 225 return thread.hwrei(); 226#else 227 return NoFault; 228#endif 229 } 230 231 bool 232 simPalCheck(int palFunc) 233 { 234#if THE_ISA == ALPHA_ISA 235 return thread.simPalCheck(palFunc); 236#else 237 return false; 238#endif 239 } 240 241 void 242 syscall(int64_t callnum) 243 { 244 if (FullSystem) 245 panic("Syscall emulation isn't available in FS mode.\n"); 246 247 thread.syscall(callnum); 248 } 249 250 ThreadContext *tcBase() { return thread.getTC(); } 251 252 /* @todo, should make stCondFailures persistent somewhere */ 253 unsigned int readStCondFailures() { return 0; } 254 unsigned int 255 setStCondFailures(unsigned int st_cond_failures) 256 { 257 return 0; 258 } 259 260 int contextId() { return thread.contextId(); } 261 /* ISA-specific (or at least currently ISA singleton) functions */ 262 263 /* X86: TLB twiddling */ 264 void 265 demapPage(Addr vaddr, uint64_t asn) 266 { 267 thread.getITBPtr()->demapPage(vaddr, asn); 268 thread.getDTBPtr()->demapPage(vaddr, asn); 269 } 270 271 TheISA::CCReg 272 readCCRegOperand(const StaticInst *si, int idx) 273 { 274 int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; 275 return thread.readCCReg(reg_idx); 276 } 277 278 void 279 setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) 280 { 281 int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; 282 thread.setCCReg(reg_idx, val); 283 } 284 285 void 286 demapInstPage(Addr vaddr, uint64_t asn) 287 { 288 thread.getITBPtr()->demapPage(vaddr, asn); 289 } 290 291 void 292 demapDataPage(Addr vaddr, uint64_t asn) 293 { 294 thread.getDTBPtr()->demapPage(vaddr, asn); 295 } 296 297 /* ALPHA/POWER: Effective address storage */ 298 void setEA(Addr &ea) 299 { 300 inst->ea = ea; 301 } 302 303 BaseCPU *getCpuPtr() { return &cpu; } 304 305 /* POWER: Effective address storage */ 306 Addr getEA() 307 { 308 return inst->ea; 309 } 310 311 /* MIPS: other thread register reading/writing */ 312 uint64_t 313 readRegOtherThread(unsigned idx, ThreadID tid = InvalidThreadID) 314 { 315 SimpleThread *other_thread = (tid == InvalidThreadID 316 ? &thread : cpu.threads[tid]); 317 318 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 319 return other_thread->readIntReg(idx); 320 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 321 return other_thread->readFloatRegBits(idx 322 - TheISA::FP_Reg_Base); 323 } else { /* Misc */ 324 return other_thread->readMiscReg(idx 325 - TheISA::Misc_Reg_Base); 326 } 327 } 328 329 void 330 setRegOtherThread(unsigned idx, const TheISA::MiscReg &val, 331 ThreadID tid = InvalidThreadID) 332 { 333 SimpleThread *other_thread = (tid == InvalidThreadID 334 ? &thread : cpu.threads[tid]); 335 336 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 337 return other_thread->setIntReg(idx, val); 338 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 339 return other_thread->setFloatRegBits(idx 340 - TheISA::FP_Reg_Base, val); 341 } else { /* Misc */ 342 return other_thread->setMiscReg(idx 343 - TheISA::Misc_Reg_Base, val); 344 } 345 } 346}; 347 348} 349 350#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ 351