types.hh revision 7720:65d338a8dba4
1/* 2 * Copyright (c) 2010 Gabe Black 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: Gabe Black 29 */ 30 31#ifndef __ARCH_GENERIC_TYPES_HH__ 32#define __ARCH_GENERIC_TYPES_HH__ 33 34#include <iostream> 35 36#include "base/types.hh" 37#include "base/trace.hh" 38#include "sim/serialize.hh" 39 40namespace GenericISA 41{ 42 43// The guaranteed interface. 44class PCStateBase 45{ 46 protected: 47 Addr _pc; 48 Addr _npc; 49 50 PCStateBase() {} 51 PCStateBase(Addr val) { set(val); } 52 53 public: 54 /** 55 * Returns the memory address the bytes of this instruction came from. 56 * 57 * @return Memory address of the current instruction's encoding. 58 */ 59 Addr 60 instAddr() const 61 { 62 return _pc; 63 } 64 65 /** 66 * Returns the memory address the bytes of the next instruction came from. 67 * 68 * @return Memory address of the next instruction's encoding. 69 */ 70 Addr 71 nextInstAddr() const 72 { 73 return _npc; 74 } 75 76 /** 77 * Returns the current micropc. 78 * 79 * @return The current micropc. 80 */ 81 MicroPC 82 microPC() const 83 { 84 return 0; 85 } 86 87 /** 88 * Force this PC to reflect a particular value, resetting all its other 89 * fields around it. This is useful for in place (re)initialization. 90 * 91 * @param val The value to set the PC to. 92 */ 93 void set(Addr val); 94 95 bool 96 operator == (const PCStateBase &opc) const 97 { 98 return _pc == opc._pc && _npc == opc._npc; 99 } 100 101 void 102 serialize(std::ostream &os) 103 { 104 SERIALIZE_SCALAR(_pc); 105 SERIALIZE_SCALAR(_npc); 106 } 107 108 void 109 unserialize(Checkpoint *cp, const std::string §ion) 110 { 111 UNSERIALIZE_SCALAR(_pc); 112 UNSERIALIZE_SCALAR(_npc); 113 } 114}; 115 116 117/* 118 * Different flavors of PC state. Only ISA specific code should rely on 119 * any particular type of PC state being available. All other code should 120 * use the interface above. 121 */ 122 123// The most basic type of PC. 124template <class MachInst> 125class SimplePCState : public PCStateBase 126{ 127 protected: 128 typedef PCStateBase Base; 129 130 public: 131 132 Addr pc() const { return _pc; } 133 void pc(Addr val) { _pc = val; } 134 135 Addr npc() const { return _npc; } 136 void npc(Addr val) { _npc = val; } 137 138 void 139 set(Addr val) 140 { 141 pc(val); 142 npc(val + sizeof(MachInst)); 143 }; 144 145 SimplePCState() {} 146 SimplePCState(Addr val) { set(val); } 147 148 bool 149 branching() const 150 { 151 return this->npc() != this->pc() + sizeof(MachInst); 152 } 153 154 // Advance the PC. 155 void 156 advance() 157 { 158 _pc = _npc; 159 _npc += sizeof(MachInst); 160 } 161}; 162 163template <class MachInst> 164std::ostream & 165operator<<(std::ostream & os, const SimplePCState<MachInst> &pc) 166{ 167 ccprintf(os, "(%#x=>%#x)", pc.pc(), pc.npc()); 168 return os; 169} 170 171// A PC and microcode PC. 172template <class MachInst> 173class UPCState : public SimplePCState<MachInst> 174{ 175 protected: 176 typedef SimplePCState<MachInst> Base; 177 178 MicroPC _upc; 179 MicroPC _nupc; 180 181 public: 182 183 MicroPC upc() const { return _upc; } 184 void upc(MicroPC val) { _upc = val; } 185 186 MicroPC nupc() const { return _nupc; } 187 void nupc(MicroPC val) { _nupc = val; } 188 189 MicroPC 190 microPC() const 191 { 192 return _upc; 193 } 194 195 void 196 set(Addr val) 197 { 198 Base::set(val); 199 upc(0); 200 nupc(1); 201 } 202 203 UPCState() {} 204 UPCState(Addr val) { set(val); } 205 206 bool 207 branching() const 208 { 209 return this->npc() != this->pc() + sizeof(MachInst) || 210 this->nupc() != this->upc() + 1; 211 } 212 213 // Advance the upc within the instruction. 214 void 215 uAdvance() 216 { 217 _upc = _nupc; 218 _nupc++; 219 } 220 221 // End the macroop by resetting the upc and advancing the regular pc. 222 void 223 uEnd() 224 { 225 this->advance(); 226 _upc = 0; 227 _nupc = 1; 228 } 229 230 bool 231 operator == (const UPCState<MachInst> &opc) const 232 { 233 return Base::_pc == opc._pc && 234 Base::_npc == opc._npc && 235 _upc == opc._upc && _nupc == opc._nupc; 236 } 237 238 void 239 serialize(std::ostream &os) 240 { 241 Base::serialize(os); 242 SERIALIZE_SCALAR(_upc); 243 SERIALIZE_SCALAR(_nupc); 244 } 245 246 void 247 unserialize(Checkpoint *cp, const std::string §ion) 248 { 249 Base::unserialize(cp, section); 250 UNSERIALIZE_SCALAR(_upc); 251 UNSERIALIZE_SCALAR(_nupc); 252 } 253}; 254 255template <class MachInst> 256std::ostream & 257operator<<(std::ostream & os, const UPCState<MachInst> &pc) 258{ 259 ccprintf(os, "(%#x=>%#x).(%d=>%d)", 260 pc.pc(), pc.npc(), pc.upc(), pc.npc()); 261 return os; 262} 263 264// A PC with a delay slot. 265template <class MachInst> 266class DelaySlotPCState : public SimplePCState<MachInst> 267{ 268 protected: 269 typedef SimplePCState<MachInst> Base; 270 271 Addr _nnpc; 272 273 public: 274 275 Addr nnpc() const { return _nnpc; } 276 void nnpc(Addr val) { _nnpc = val; } 277 278 void 279 set(Addr val) 280 { 281 Base::set(val); 282 nnpc(val + 2 * sizeof(MachInst)); 283 } 284 285 DelaySlotPCState() {} 286 DelaySlotPCState(Addr val) { set(val); } 287 288 bool 289 branching() const 290 { 291 return !(this->nnpc() == this->npc() + sizeof(MachInst) && 292 (this->npc() == this->pc() + sizeof(MachInst) || 293 this->npc() == this->pc() + 2 * sizeof(MachInst))); 294 } 295 296 // Advance the PC. 297 void 298 advance() 299 { 300 Base::_pc = Base::_npc; 301 Base::_npc = _nnpc; 302 _nnpc += sizeof(MachInst); 303 } 304 305 bool 306 operator == (const DelaySlotPCState<MachInst> &opc) const 307 { 308 return Base::_pc == opc._pc && 309 Base::_npc == opc._npc && 310 _nnpc == opc._nnpc; 311 } 312 313 void 314 serialize(std::ostream &os) 315 { 316 Base::serialize(os); 317 SERIALIZE_SCALAR(_nnpc); 318 } 319 320 void 321 unserialize(Checkpoint *cp, const std::string §ion) 322 { 323 Base::unserialize(cp, section); 324 UNSERIALIZE_SCALAR(_nnpc); 325 } 326}; 327 328template <class MachInst> 329std::ostream & 330operator<<(std::ostream & os, const DelaySlotPCState<MachInst> &pc) 331{ 332 ccprintf(os, "(%#x=>%#x=>%#x)", 333 pc.pc(), pc.npc(), pc.nnpc()); 334 return os; 335} 336 337// A PC with a delay slot and a microcode PC. 338template <class MachInst> 339class DelaySlotUPCState : public DelaySlotPCState<MachInst> 340{ 341 protected: 342 typedef DelaySlotPCState<MachInst> Base; 343 344 MicroPC _upc; 345 MicroPC _nupc; 346 347 public: 348 349 MicroPC upc() const { return _upc; } 350 void upc(MicroPC val) { _upc = val; } 351 352 MicroPC nupc() const { return _nupc; } 353 void nupc(MicroPC val) { _nupc = val; } 354 355 MicroPC 356 microPC() const 357 { 358 return _upc; 359 } 360 361 void 362 set(Addr val) 363 { 364 Base::set(val); 365 upc(0); 366 nupc(1); 367 } 368 369 DelaySlotUPCState() {} 370 DelaySlotUPCState(Addr val) { set(val); } 371 372 bool 373 branching() const 374 { 375 return Base::branching() || this->nupc() != this->upc() + 1; 376 } 377 378 // Advance the upc within the instruction. 379 void 380 uAdvance() 381 { 382 _upc = _nupc; 383 _nupc++; 384 } 385 386 // End the macroop by resetting the upc and advancing the regular pc. 387 void 388 uEnd() 389 { 390 this->advance(); 391 _upc = 0; 392 _nupc = 1; 393 } 394 395 bool 396 operator == (const DelaySlotUPCState<MachInst> &opc) const 397 { 398 return Base::_pc == opc._pc && 399 Base::_npc == opc._npc && 400 Base::_nnpc == opc._nnpc && 401 _upc == opc._upc && _nupc == opc._nupc; 402 } 403 404 void 405 serialize(std::ostream &os) 406 { 407 Base::serialize(os); 408 SERIALIZE_SCALAR(_upc); 409 SERIALIZE_SCALAR(_nupc); 410 } 411 412 void 413 unserialize(Checkpoint *cp, const std::string §ion) 414 { 415 Base::unserialize(cp, section); 416 UNSERIALIZE_SCALAR(_upc); 417 UNSERIALIZE_SCALAR(_nupc); 418 } 419}; 420 421template <class MachInst> 422std::ostream & 423operator<<(std::ostream & os, const DelaySlotUPCState<MachInst> &pc) 424{ 425 ccprintf(os, "(%#x=>%#x=>%#x).(%d=>%d)", 426 pc.pc(), pc.npc(), pc.nnpc(), pc.upc(), pc.nupc()); 427 return os; 428} 429 430} 431 432#endif 433