types.hh revision 11168:f98eb2da15a4
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/trace.hh" 37#include "base/types.hh" 38#include "sim/serialize.hh" 39 40namespace GenericISA 41{ 42 43// The guaranteed interface. 44class PCStateBase : public Serializable 45{ 46 protected: 47 Addr _pc; 48 Addr _npc; 49 50 PCStateBase() : _pc(0), _npc(0) {} 51 PCStateBase(Addr val) : _pc(0), _npc(0) { 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 bool 102 operator != (const PCStateBase &opc) const 103 { 104 return !(*this == opc); 105 } 106 107 void 108 serialize(CheckpointOut &cp) const override 109 { 110 SERIALIZE_SCALAR(_pc); 111 SERIALIZE_SCALAR(_npc); 112 } 113 114 void 115 unserialize(CheckpointIn &cp) override 116 { 117 UNSERIALIZE_SCALAR(_pc); 118 UNSERIALIZE_SCALAR(_npc); 119 } 120}; 121 122 123/* 124 * Different flavors of PC state. Only ISA specific code should rely on 125 * any particular type of PC state being available. All other code should 126 * use the interface above. 127 */ 128 129// The most basic type of PC. 130template <class MachInst> 131class SimplePCState : public PCStateBase 132{ 133 protected: 134 typedef PCStateBase Base; 135 136 public: 137 138 Addr pc() const { return _pc; } 139 void pc(Addr val) { _pc = val; } 140 141 Addr npc() const { return _npc; } 142 void npc(Addr val) { _npc = val; } 143 144 void 145 set(Addr val) 146 { 147 pc(val); 148 npc(val + sizeof(MachInst)); 149 }; 150 151 SimplePCState() {} 152 SimplePCState(Addr val) { set(val); } 153 154 bool 155 branching() const 156 { 157 return this->npc() != this->pc() + sizeof(MachInst); 158 } 159 160 // Advance the PC. 161 void 162 advance() 163 { 164 _pc = _npc; 165 _npc += sizeof(MachInst); 166 } 167}; 168 169template <class MachInst> 170std::ostream & 171operator<<(std::ostream & os, const SimplePCState<MachInst> &pc) 172{ 173 ccprintf(os, "(%#x=>%#x)", pc.pc(), pc.npc()); 174 return os; 175} 176 177// A PC and microcode PC. 178template <class MachInst> 179class UPCState : public SimplePCState<MachInst> 180{ 181 protected: 182 typedef SimplePCState<MachInst> Base; 183 184 MicroPC _upc; 185 MicroPC _nupc; 186 187 public: 188 189 MicroPC upc() const { return _upc; } 190 void upc(MicroPC val) { _upc = val; } 191 192 MicroPC nupc() const { return _nupc; } 193 void nupc(MicroPC val) { _nupc = val; } 194 195 MicroPC 196 microPC() const 197 { 198 return _upc; 199 } 200 201 void 202 set(Addr val) 203 { 204 Base::set(val); 205 upc(0); 206 nupc(1); 207 } 208 209 UPCState() : _upc(0), _nupc(0) {} 210 UPCState(Addr val) : _upc(0), _nupc(0) { set(val); } 211 212 bool 213 branching() const 214 { 215 return this->npc() != this->pc() + sizeof(MachInst) || 216 this->nupc() != this->upc() + 1; 217 } 218 219 // Advance the upc within the instruction. 220 void 221 uAdvance() 222 { 223 _upc = _nupc; 224 _nupc++; 225 } 226 227 // End the macroop by resetting the upc and advancing the regular pc. 228 void 229 uEnd() 230 { 231 this->advance(); 232 _upc = 0; 233 _nupc = 1; 234 } 235 236 bool 237 operator == (const UPCState<MachInst> &opc) const 238 { 239 return Base::_pc == opc._pc && 240 Base::_npc == opc._npc && 241 _upc == opc._upc && _nupc == opc._nupc; 242 } 243 244 bool 245 operator != (const UPCState<MachInst> &opc) const 246 { 247 return !(*this == opc); 248 } 249 250 void 251 serialize(CheckpointOut &cp) const override 252 { 253 Base::serialize(cp); 254 SERIALIZE_SCALAR(_upc); 255 SERIALIZE_SCALAR(_nupc); 256 } 257 258 void 259 unserialize(CheckpointIn &cp) override 260 { 261 Base::unserialize(cp); 262 UNSERIALIZE_SCALAR(_upc); 263 UNSERIALIZE_SCALAR(_nupc); 264 } 265}; 266 267template <class MachInst> 268std::ostream & 269operator<<(std::ostream & os, const UPCState<MachInst> &pc) 270{ 271 ccprintf(os, "(%#x=>%#x).(%d=>%d)", 272 pc.pc(), pc.npc(), pc.upc(), pc.nupc()); 273 return os; 274} 275 276// A PC with a delay slot. 277template <class MachInst> 278class DelaySlotPCState : public SimplePCState<MachInst> 279{ 280 protected: 281 typedef SimplePCState<MachInst> Base; 282 283 Addr _nnpc; 284 285 public: 286 287 Addr nnpc() const { return _nnpc; } 288 void nnpc(Addr val) { _nnpc = val; } 289 290 void 291 set(Addr val) 292 { 293 Base::set(val); 294 nnpc(val + 2 * sizeof(MachInst)); 295 } 296 297 DelaySlotPCState() {} 298 DelaySlotPCState(Addr val) { set(val); } 299 300 bool 301 branching() const 302 { 303 return !(this->nnpc() == this->npc() + sizeof(MachInst) && 304 (this->npc() == this->pc() + sizeof(MachInst) || 305 this->npc() == this->pc() + 2 * sizeof(MachInst))); 306 } 307 308 // Advance the PC. 309 void 310 advance() 311 { 312 Base::_pc = Base::_npc; 313 Base::_npc = _nnpc; 314 _nnpc += sizeof(MachInst); 315 } 316 317 bool 318 operator == (const DelaySlotPCState<MachInst> &opc) const 319 { 320 return Base::_pc == opc._pc && 321 Base::_npc == opc._npc && 322 _nnpc == opc._nnpc; 323 } 324 325 bool 326 operator != (const DelaySlotPCState<MachInst> &opc) const 327 { 328 return !(*this == opc); 329 } 330 331 void 332 serialize(CheckpointOut &cp) const override 333 { 334 Base::serialize(cp); 335 SERIALIZE_SCALAR(_nnpc); 336 } 337 338 void 339 unserialize(CheckpointIn &cp) override 340 { 341 Base::unserialize(cp); 342 UNSERIALIZE_SCALAR(_nnpc); 343 } 344}; 345 346template <class MachInst> 347std::ostream & 348operator<<(std::ostream & os, const DelaySlotPCState<MachInst> &pc) 349{ 350 ccprintf(os, "(%#x=>%#x=>%#x)", 351 pc.pc(), pc.npc(), pc.nnpc()); 352 return os; 353} 354 355// A PC with a delay slot and a microcode PC. 356template <class MachInst> 357class DelaySlotUPCState : public DelaySlotPCState<MachInst> 358{ 359 protected: 360 typedef DelaySlotPCState<MachInst> Base; 361 362 MicroPC _upc; 363 MicroPC _nupc; 364 365 public: 366 367 MicroPC upc() const { return _upc; } 368 void upc(MicroPC val) { _upc = val; } 369 370 MicroPC nupc() const { return _nupc; } 371 void nupc(MicroPC val) { _nupc = val; } 372 373 MicroPC 374 microPC() const 375 { 376 return _upc; 377 } 378 379 void 380 set(Addr val) 381 { 382 Base::set(val); 383 upc(0); 384 nupc(1); 385 } 386 387 DelaySlotUPCState() {} 388 DelaySlotUPCState(Addr val) { set(val); } 389 390 bool 391 branching() const 392 { 393 return Base::branching() || this->nupc() != this->upc() + 1; 394 } 395 396 // Advance the upc within the instruction. 397 void 398 uAdvance() 399 { 400 _upc = _nupc; 401 _nupc++; 402 } 403 404 // End the macroop by resetting the upc and advancing the regular pc. 405 void 406 uEnd() 407 { 408 this->advance(); 409 _upc = 0; 410 _nupc = 1; 411 } 412 413 bool 414 operator == (const DelaySlotUPCState<MachInst> &opc) const 415 { 416 return Base::_pc == opc._pc && 417 Base::_npc == opc._npc && 418 Base::_nnpc == opc._nnpc && 419 _upc == opc._upc && _nupc == opc._nupc; 420 } 421 422 bool 423 operator != (const DelaySlotUPCState<MachInst> &opc) const 424 { 425 return !(*this == opc); 426 } 427 428 void 429 serialize(CheckpointOut &cp) const override 430 { 431 Base::serialize(cp); 432 SERIALIZE_SCALAR(_upc); 433 SERIALIZE_SCALAR(_nupc); 434 } 435 436 void 437 unserialize(CheckpointIn &cp) override 438 { 439 Base::unserialize(cp); 440 UNSERIALIZE_SCALAR(_upc); 441 UNSERIALIZE_SCALAR(_nupc); 442 } 443}; 444 445template <class MachInst> 446std::ostream & 447operator<<(std::ostream & os, const DelaySlotUPCState<MachInst> &pc) 448{ 449 ccprintf(os, "(%#x=>%#x=>%#x).(%d=>%d)", 450 pc.pc(), pc.npc(), pc.nnpc(), pc.upc(), pc.nupc()); 451 return os; 452} 453 454} 455 456#endif 457