registers.hh revision 2665
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 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 * Ali Saidi 30 */ 31 32#ifndef __ARCH_SPARC_REGFILE_HH__ 33#define __ARCH_SPARC_REGFILE_HH__ 34 35#include "arch/sparc/exceptions.hh" 36#include "arch/sparc/faults.hh" 37#include "base/trace.hh" 38#include "sim/byteswap.hh" 39#include "cpu/cpuevent.hh" 40#include "sim/host.hh" 41 42class Checkpoint; 43 44namespace SparcISA 45{ 46 47 typedef uint8_t RegIndex; 48 49 // MAXTL - maximum trap level 50 const int MaxPTL = 2; 51 const int MaxTL = 6; 52 const int MaxGL = 3; 53 const int MaxPGL = 2; 54 55 // NWINDOWS - number of register windows, can be 3 to 32 56 const int NWindows = 32; 57 58 59 const int AsrStart = 0; 60 const int PrStart = 32; 61 const int HprStart = 64; 62 const int MiscStart = 96; 63 64 65 const uint64_t Bit64 = 0x8000000000000000; 66 67 class IntRegFile 68 { 69 protected: 70 static const int FrameOffsetBits = 3; 71 static const int FrameNumBits = 2; 72 73 static const int RegsPerFrame = 1 << FrameOffsetBits; 74 static const int FrameNumMask = 75 (FrameNumBits == sizeof(int)) ? 76 (unsigned int)(-1) : 77 (1 << FrameNumBits) - 1; 78 static const int FrameOffsetMask = 79 (FrameOffsetBits == sizeof(int)) ? 80 (unsigned int)(-1) : 81 (1 << FrameOffsetBits) - 1; 82 83 IntReg regGlobals[MaxGL][RegsPerFrame]; 84 IntReg regSegments[2 * NWindows][RegsPerFrame]; 85 86 enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; 87 88 IntReg * regView[NumFrames]; 89 90 static const int RegGlobalOffset = 0; 91 static const int FrameOffset = MaxGL * RegsPerFrame; 92 int offset[NumFrames]; 93 94 public: 95 96 int flattenIndex(int reg) 97 { 98 int flatIndex = offset[reg >> FrameOffsetBits] 99 | (reg & FrameOffsetMask); 100 DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex); 101 return flatIndex; 102 } 103 104 void clear() 105 { 106 int x; 107 for (x = 0; x < MaxGL; x++) 108 memset(regGlobals[x], 0, sizeof(regGlobals[x])); 109 for(int x = 0; x < 2 * NWindows; x++) 110 bzero(regSegments[x], sizeof(regSegments[x])); 111 } 112 113 IntRegFile() 114 { 115 offset[Globals] = 0; 116 regView[Globals] = regGlobals[0]; 117 setCWP(0); 118 clear(); 119 } 120 121 IntReg readReg(int intReg) 122 { 123 IntReg val = 124 regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; 125 DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); 126 return val; 127 } 128 129 Fault setReg(int intReg, const IntReg &val) 130 { 131 if(intReg) 132 DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); 133 regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; 134 return NoFault; 135 } 136 137 //This doesn't effect the actual CWP register. 138 //It's purpose is to adjust the view of the register file 139 //to what it would be if CWP = cwp. 140 void setCWP(int cwp) 141 { 142 int index = ((NWindows - cwp) % NWindows) * 2; 143 offset[Outputs] = FrameOffset + (index * RegsPerFrame); 144 offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame); 145 offset[Inputs] = FrameOffset + 146 (((index+2) % (NWindows * 2)) * RegsPerFrame); 147 regView[Outputs] = regSegments[index]; 148 regView[Locals] = regSegments[index+1]; 149 regView[Inputs] = regSegments[(index+2) % (NWindows * 2)]; 150 151 DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp); 152 } 153 154 void setGlobals(int gl) 155 { 156 157 DPRINTF(Sparc, "Now using %d globals", gl); 158 159 regView[Globals] = regGlobals[gl]; 160 offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; 161 } 162 163 void serialize(std::ostream &os); 164 165 void unserialize(Checkpoint *cp, const std::string §ion); 166 }; 167 168 typedef float float32_t; 169 typedef double float64_t; 170 //FIXME long double refers to a 10 byte float, rather than a 171 //16 byte float as required. This data type may have to be emulated. 172 typedef double float128_t; 173 174 class FloatRegFile 175 { 176 public: 177 static const int SingleWidth = 32; 178 static const int DoubleWidth = 64; 179 static const int QuadWidth = 128; 180 181 protected: 182 183 //Since the floating point registers overlap each other, 184 //A generic storage space is used. The float to be returned is 185 //pulled from the appropriate section of this region. 186 char regSpace[SingleWidth / 8 * NumFloatRegs]; 187 188 public: 189 190 void clear() 191 { 192 bzero(regSpace, sizeof(regSpace)); 193 } 194 195 FloatReg readReg(int floatReg, int width) 196 { 197 //In each of these cases, we have to copy the value into a temporary 198 //variable. This is because we may otherwise try to access an 199 //unaligned portion of memory. 200 switch(width) 201 { 202 case SingleWidth: 203 float32_t result32; 204 memcpy(&result32, regSpace + 4 * floatReg, width); 205 return htog(result32); 206 case DoubleWidth: 207 float64_t result64; 208 memcpy(&result64, regSpace + 4 * floatReg, width); 209 return htog(result64); 210 case QuadWidth: 211 float128_t result128; 212 memcpy(&result128, regSpace + 4 * floatReg, width); 213 return htog(result128); 214 default: 215 panic("Attempted to read a %d bit floating point register!", width); 216 } 217 } 218 219 FloatRegBits readRegBits(int floatReg, int width) 220 { 221 //In each of these cases, we have to copy the value into a temporary 222 //variable. This is because we may otherwise try to access an 223 //unaligned portion of memory. 224 switch(width) 225 { 226 case SingleWidth: 227 uint32_t result32; 228 memcpy(&result32, regSpace + 4 * floatReg, width); 229 return htog(result32); 230 case DoubleWidth: 231 uint64_t result64; 232 memcpy(&result64, regSpace + 4 * floatReg, width); 233 return htog(result64); 234 case QuadWidth: 235 uint64_t result128; 236 memcpy(&result128, regSpace + 4 * floatReg, width); 237 return htog(result128); 238 default: 239 panic("Attempted to read a %d bit floating point register!", width); 240 } 241 } 242 243 Fault setReg(int floatReg, const FloatReg &val, int width) 244 { 245 //In each of these cases, we have to copy the value into a temporary 246 //variable. This is because we may otherwise try to access an 247 //unaligned portion of memory. 248 switch(width) 249 { 250 case SingleWidth: 251 uint32_t result32 = gtoh((uint32_t)val); 252 memcpy(regSpace + 4 * floatReg, &result32, width); 253 case DoubleWidth: 254 uint64_t result64 = gtoh((uint64_t)val); 255 memcpy(regSpace + 4 * floatReg, &result64, width); 256 case QuadWidth: 257 uint64_t result128 = gtoh((uint64_t)val); 258 memcpy(regSpace + 4 * floatReg, &result128, width); 259 default: 260 panic("Attempted to read a %d bit floating point register!", width); 261 } 262 return NoFault; 263 } 264 265 Fault setRegBits(int floatReg, const FloatRegBits &val, int width) 266 { 267 //In each of these cases, we have to copy the value into a temporary 268 //variable. This is because we may otherwise try to access an 269 //unaligned portion of memory. 270 switch(width) 271 { 272 case SingleWidth: 273 uint32_t result32 = gtoh((uint32_t)val); 274 memcpy(regSpace + 4 * floatReg, &result32, width); 275 case DoubleWidth: 276 uint64_t result64 = gtoh((uint64_t)val); 277 memcpy(regSpace + 4 * floatReg, &result64, width); 278 case QuadWidth: 279 uint64_t result128 = gtoh((uint64_t)val); 280 memcpy(regSpace + 4 * floatReg, &result128, width); 281 default: 282 panic("Attempted to read a %d bit floating point register!", width); 283 } 284 return NoFault; 285 } 286 287 void serialize(std::ostream &os); 288 289 void unserialize(Checkpoint *cp, const std::string §ion); 290 }; 291 292 enum MiscRegIndex 293 { 294 /** Ancillary State Registers */ 295 MISCREG_Y = AsrStart + 0, 296 MISCREG_CCR = AsrStart + 2, 297 MISCREG_ASI = AsrStart + 3, 298 MISCREG_TICK = AsrStart + 4, 299 MISCREG_PC = AsrStart + 5, 300 MISCREG_FPRS = AsrStart + 6, 301 MISCREG_PCR = AsrStart + 16, 302 MISCREG_PIC = AsrStart + 17, 303 MISCREG_GSR = AsrStart + 19, 304 MISCREG_SOFTINT_SET = AsrStart + 20, 305 MISCREG_SOFTINT_CLR = AsrStart + 21, 306 MISCREG_SOFTINT = AsrStart + 22, 307 MISCREG_TICK_CMPR = AsrStart + 23, 308 MISCREG_STICK = AsrStart + 24, 309 MISCREG_STICK_CMPR = AsrStart + 25, 310 311 /** Privilged Registers */ 312 MISCREG_TPC = PrStart + 0, 313 MISCREG_TNPC = PrStart + 1, 314 MISCREG_TSTATE = PrStart + 2, 315 MISCREG_TT = PrStart + 3, 316 MISCREG_PRIVTICK = PrStart + 4, 317 MISCREG_TBA = PrStart + 5, 318 MISCREG_PSTATE = PrStart + 6, 319 MISCREG_TL = PrStart + 7, 320 MISCREG_PIL = PrStart + 8, 321 MISCREG_CWP = PrStart + 9, 322 MISCREG_CANSAVE = PrStart + 10, 323 MISCREG_CANRESTORE = PrStart + 11, 324 MISCREG_CLEANWIN = PrStart + 12, 325 MISCREG_OTHERWIN = PrStart + 13, 326 MISCREG_WSTATE = PrStart + 14, 327 MISCREG_GL = PrStart + 16, 328 329 /** Hyper privileged registers */ 330 MISCREG_HPSTATE = HprStart + 0, 331 MISCREG_HTSTATE = HprStart + 1, 332 MISCREG_HINTP = HprStart + 3, 333 MISCREG_HTBA = HprStart + 5, 334 MISCREG_HVER = HprStart + 6, 335 MISCREG_STRAND_STS_REG = HprStart + 16, 336 MISCREG_HSTICK_CMPR = HprStart + 31, 337 338 /** Floating Point Status Register */ 339 MISCREG_FSR = MiscStart + 0 340 341 }; 342 343 // The control registers, broken out into fields 344 class MiscRegFile 345 { 346 private: 347 348 /* ASR Registers */ 349 union { 350 uint64_t y; // Y (used in obsolete multiplication) 351 struct { 352 uint64_t value:32; // The actual value stored in y 353 uint64_t :32; // reserved bits 354 } yFields; 355 }; 356 union { 357 uint8_t ccr; // Condition Code Register 358 struct { 359 union { 360 uint8_t icc:4; // 32-bit condition codes 361 struct { 362 uint8_t c:1; // Carry 363 uint8_t v:1; // Overflow 364 uint8_t z:1; // Zero 365 uint8_t n:1; // Negative 366 } iccFields; 367 }; 368 union { 369 uint8_t xcc:4; // 64-bit condition codes 370 struct { 371 uint8_t c:1; // Carry 372 uint8_t v:1; // Overflow 373 uint8_t z:1; // Zero 374 uint8_t n:1; // Negative 375 } xccFields; 376 }; 377 } ccrFields; 378 }; 379 uint8_t asi; // Address Space Identifier 380 union { 381 uint64_t tick; // Hardware clock-tick counter 382 struct { 383 int64_t counter:63; // Clock-tick count 384 uint64_t npt:1; // Non-priveleged trap 385 } tickFields; 386 }; 387 union { 388 uint8_t fprs; // Floating-Point Register State 389 struct { 390 uint8_t dl:1; // Dirty lower 391 uint8_t du:1; // Dirty upper 392 uint8_t fef:1; // FPRS enable floating-Point 393 } fprsFields; 394 }; 395 union { 396 uint64_t softint; 397 struct { 398 uint64_t tm:1; 399 uint64_t int_level:14; 400 uint64_t sm:1; 401 } softintFields; 402 }; 403 union { 404 uint64_t tick_cmpr; // Hardware tick compare registers 405 struct { 406 uint64_t tick_cmpr:63; // Clock-tick count 407 uint64_t int_dis:1; // Non-priveleged trap 408 } tick_cmprFields; 409 }; 410 union { 411 uint64_t stick; // Hardware clock-tick counter 412 struct { 413 int64_t :63; // Not used, storage in SparcSystem 414 uint64_t npt:1; // Non-priveleged trap 415 } stickFields; 416 }; 417 union { 418 uint64_t stick_cmpr; // Hardware tick compare registers 419 struct { 420 uint64_t tick_cmpr:63; // Clock-tick count 421 uint64_t int_dis:1; // Non-priveleged trap 422 } stick_cmprFields; 423 }; 424 425 426 /* Privileged Registers */ 427 uint64_t tpc[MaxTL]; // Trap Program Counter (value from 428 // previous trap level) 429 uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from 430 // previous trap level) 431 union { 432 uint64_t tstate[MaxTL]; // Trap State 433 struct { 434 //Values are from previous trap level 435 uint64_t cwp:5; // Current Window Pointer 436 uint64_t :3; // Reserved bits 437 uint64_t pstate:13; // Process State 438 uint64_t :3; // Reserved bits 439 uint64_t asi:8; // Address Space Identifier 440 uint64_t ccr:8; // Condition Code Register 441 uint64_t gl:8; // Global level 442 } tstateFields[MaxTL]; 443 }; 444 uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured 445 // on the previous level) 446 uint64_t tba; // Trap Base Address 447 448 union { 449 uint16_t pstate; // Process State Register 450 struct { 451 uint16_t :1; // reserved 452 uint16_t ie:1; // Interrupt enable 453 uint16_t priv:1; // Privelege mode 454 uint16_t am:1; // Address mask 455 uint16_t pef:1; // PSTATE enable floating-point 456 uint16_t :1; // reserved2 457 uint16_t mm:2; // Memory Model 458 uint16_t tle:1; // Trap little-endian 459 uint16_t cle:1; // Current little-endian 460 } pstateFields; 461 }; 462 uint8_t tl; // Trap Level 463 uint8_t pil; // Process Interrupt Register 464 uint8_t cwp; // Current Window Pointer 465 uint8_t cansave; // Savable windows 466 uint8_t canrestore; // Restorable windows 467 uint8_t cleanwin; // Clean windows 468 uint8_t otherwin; // Other windows 469 union { 470 uint8_t wstate; // Window State 471 struct { 472 uint8_t normal:3; // Bits TT<4:2> are set to on a normal 473 // register window trap 474 uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" 475 // register window trap 476 } wstateFields; 477 }; 478 uint8_t gl; // Global level register 479 480 481 /** Hyperprivileged Registers */ 482 union { 483 uint64_t hpstate; // Hyperprivileged State Register 484 struct { 485 uint8_t tlz: 1; 486 uint8_t :1; 487 uint8_t hpriv:1; 488 uint8_t :2; 489 uint8_t red:1; 490 uint8_t :4; 491 uint8_t ibe:1; 492 uint8_t id:1; 493 } hpstateFields; 494 }; 495 496 uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register 497 uint64_t hintp; 498 uint64_t htba; // Hyperprivileged Trap Base Address register 499 union { 500 uint64_t hstick_cmpr; // Hardware tick compare registers 501 struct { 502 uint64_t tick_cmpr:63; // Clock-tick count 503 uint64_t int_dis:1; // Non-priveleged trap 504 } hstick_cmprFields; 505 }; 506 507 uint64_t strandStatusReg; // Per strand status register 508 509 510 /** Floating point misc registers. */ 511 union { 512 uint64_t fsr; // Floating-Point State Register 513 struct { 514 union { 515 uint64_t cexc:5; // Current excpetion 516 struct { 517 uint64_t nxc:1; // Inexact 518 uint64_t dzc:1; // Divide by zero 519 uint64_t ufc:1; // Underflow 520 uint64_t ofc:1; // Overflow 521 uint64_t nvc:1; // Invalid operand 522 } cexcFields; 523 }; 524 union { 525 uint64_t aexc:5; // Accrued exception 526 struct { 527 uint64_t nxc:1; // Inexact 528 uint64_t dzc:1; // Divide by zero 529 uint64_t ufc:1; // Underflow 530 uint64_t ofc:1; // Overflow 531 uint64_t nvc:1; // Invalid operand 532 } aexcFields; 533 }; 534 uint64_t fcc0:2; // Floating-Point condtion codes 535 uint64_t :1; // Reserved bits 536 uint64_t qne:1; // Deferred trap queue not empty 537 // with no queue, it should read 0 538 uint64_t ftt:3; // Floating-Point trap type 539 uint64_t ver:3; // Version (of the FPU) 540 uint64_t :2; // Reserved bits 541 uint64_t ns:1; // Nonstandard floating point 542 union { 543 uint64_t tem:5; // Trap Enable Mask 544 struct { 545 uint64_t nxm:1; // Inexact 546 uint64_t dzm:1; // Divide by zero 547 uint64_t ufm:1; // Underflow 548 uint64_t ofm:1; // Overflow 549 uint64_t nvm:1; // Invalid operand 550 } temFields; 551 }; 552 uint64_t :2; // Reserved bits 553 uint64_t rd:2; // Rounding direction 554 uint64_t fcc1:2; // Floating-Point condition codes 555 uint64_t fcc2:2; // Floating-Point condition codes 556 uint64_t fcc3:2; // Floating-Point condition codes 557 uint64_t :26; // Reserved bits 558 } fsrFields; 559 }; 560 561 // These need to check the int_dis field and if 0 then 562 // set appropriate bit in softint and checkinterrutps on the cpu 563#if FULL_SYSTEM 564 /** Process a tick compare event and generate an interrupt on the cpu if 565 * appropriate. */ 566 void processTickCompare(ExecContext *xc); 567 void processSTickCompare(ExecContext *xc); 568 void processHSTickCompare(ExecContext *xc); 569 570 typedef CpuEventWrapper<MiscRegFile, 571 &MiscRegFile::processTickCompare> TickCompareEvent; 572 TickCompareEvent *tickCompare; 573 574 typedef CpuEventWrapper<MiscRegFile, 575 &MiscRegFile::processSTickCompare> STickCompareEvent; 576 STickCompareEvent *sTickCompare; 577 578 typedef CpuEventWrapper<MiscRegFile, 579 &MiscRegFile::processHSTickCompare> HSTickCompareEvent; 580 HSTickCompareEvent *hSTickCompare; 581 582 /** Fullsystem only register version of ReadRegWithEffect() */ 583 MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ExecContext *xc); 584 /** Fullsystem only register version of SetRegWithEffect() */ 585 Fault setFSRegWithEffect(int miscReg, const MiscReg &val, 586 ExecContext * xc); 587#endif 588 public: 589 590 void reset() 591 { 592 pstateFields.pef = 0; //No FPU 593 //pstateFields.pef = 1; //FPU 594#if FULL_SYSTEM 595 //For SPARC, when a system is first started, there is a power 596 //on reset Trap which sets the processor into the following state. 597 //Bits that aren't set aren't defined on startup. 598 tl = MaxTL; 599 gl = MaxGL; 600 601 tickFields.counter = 0; //The TICK register is unreadable bya 602 tickFields.npt = 1; //The TICK register is unreadable by by !priv 603 604 softint = 0; // Clear all the soft interrupt bits 605 tick_cmprFields.int_dis = 1; // disable timer compare interrupts 606 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 607 stickFields.npt = 1; //The TICK register is unreadable by by !priv 608 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 609 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 610 611 612 tt[tl] = power_on_reset; 613 pstate = 0; // fields 0 but pef 614 pstateFields.pef = 1; 615 616 hpstate = 0; 617 hpstateFields.red = 1; 618 hpstateFields.hpriv = 1; 619 hpstateFields.tlz = 0; // this is a guess 620 621 hintp = 0; // no interrupts pending 622 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 623 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 624 625#else 626/* //This sets up the initial state of the processor for usermode processes 627 pstateFields.priv = 0; //Process runs in user mode 628 pstateFields.ie = 1; //Interrupts are enabled 629 fsrFields.rd = 0; //Round to nearest 630 fsrFields.tem = 0; //Floating point traps not enabled 631 fsrFields.ns = 0; //Non standard mode off 632 fsrFields.qne = 0; //Floating point queue is empty 633 fsrFields.aexc = 0; //No accrued exceptions 634 fsrFields.cexc = 0; //No current exceptions 635 636 //Register window management registers 637 otherwin = 0; //No windows contain info from other programs 638 canrestore = 0; //There are no windows to pop 639 cansave = MaxTL - 2; //All windows are available to save into 640 cleanwin = MaxTL;*/ 641#endif 642 } 643 644 MiscRegFile() 645 { 646 reset(); 647 } 648 649 /** read a value out of an either an SE or FS IPR. No checking is done 650 * about SE vs. FS as this is mostly used to copy the regfile. Thus more 651 * register are copied that are necessary for FS. However this prevents 652 * a bunch of ifdefs and is rarely called so is not performance 653 * criticial. */ 654 MiscReg readReg(int miscReg); 655 656 /** Read a value from an IPR. Only the SE iprs are here and the rest 657 * are are readFSRegWithEffect (which is called by readRegWithEffect()). 658 * Checking is done for permission based on state bits in the miscreg 659 * file. */ 660 MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc); 661 662 /** write a value into an either an SE or FS IPR. No checking is done 663 * about SE vs. FS as this is mostly used to copy the regfile. Thus more 664 * register are copied that are necessary for FS. However this prevents 665 * a bunch of ifdefs and is rarely called so is not performance 666 * criticial.*/ 667 Fault setReg(int miscReg, const MiscReg &val); 668 669 /** Write a value into an IPR. Only the SE iprs are here and the rest 670 * are are setFSRegWithEffect (which is called by setRegWithEffect()). 671 * Checking is done for permission based on state bits in the miscreg 672 * file. */ 673 Fault setRegWithEffect(int miscReg, 674 const MiscReg &val, ExecContext * xc); 675 676 void serialize(std::ostream & os); 677 678 void unserialize(Checkpoint * cp, const std::string & section); 679 680 void copyMiscRegs(ExecContext * xc); 681 682 bool isHyperPriv() { return hpstateFields.hpriv; } 683 bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } 684 bool isNonPriv() { return !isPriv(); } 685 }; 686 687 typedef union 688 { 689 IntReg intreg; 690 FloatReg fpreg; 691 MiscReg ctrlreg; 692 } AnyReg; 693 694 class RegFile 695 { 696 protected: 697 Addr pc; // Program Counter 698 Addr npc; // Next Program Counter 699 Addr nnpc; 700 701 public: 702 Addr readPC() 703 { 704 return pc; 705 } 706 707 void setPC(Addr val) 708 { 709 pc = val; 710 } 711 712 Addr readNextPC() 713 { 714 return npc; 715 } 716 717 void setNextPC(Addr val) 718 { 719 npc = val; 720 } 721 722 Addr readNextNPC() 723 { 724 return nnpc; 725 } 726 727 void setNextNPC(Addr val) 728 { 729 nnpc = val; 730 } 731 732 protected: 733 IntRegFile intRegFile; // integer register file 734 FloatRegFile floatRegFile; // floating point register file 735 MiscRegFile miscRegFile; // control register file 736 737 public: 738 739 void clear() 740 { 741 intRegFile.clear(); 742 floatRegFile.clear(); 743 } 744 745 int FlattenIntIndex(int reg) 746 { 747 return intRegFile.flattenIndex(reg); 748 } 749 750 MiscReg readMiscReg(int miscReg) 751 { 752 return miscRegFile.readReg(miscReg); 753 } 754 755 MiscReg readMiscRegWithEffect(int miscReg, 756 Fault &fault, ExecContext *xc) 757 { 758 return miscRegFile.readRegWithEffect(miscReg, fault, xc); 759 } 760 761 Fault setMiscReg(int miscReg, const MiscReg &val) 762 { 763 return miscRegFile.setReg(miscReg, val); 764 } 765 766 Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, 767 ExecContext * xc) 768 { 769 return miscRegFile.setRegWithEffect(miscReg, val, xc); 770 } 771 772 FloatReg readFloatReg(int floatReg, int width) 773 { 774 return floatRegFile.readReg(floatReg, width); 775 } 776 777 FloatReg readFloatReg(int floatReg) 778 { 779 //Use the "natural" width of a single float 780 return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth); 781 } 782 783 FloatRegBits readFloatRegBits(int floatReg, int width) 784 { 785 return floatRegFile.readRegBits(floatReg, width); 786 } 787 788 FloatRegBits readFloatRegBits(int floatReg) 789 { 790 //Use the "natural" width of a single float 791 return floatRegFile.readRegBits(floatReg, 792 FloatRegFile::SingleWidth); 793 } 794 795 Fault setFloatReg(int floatReg, const FloatReg &val, int width) 796 { 797 return floatRegFile.setReg(floatReg, val, width); 798 } 799 800 Fault setFloatReg(int floatReg, const FloatReg &val) 801 { 802 //Use the "natural" width of a single float 803 return setFloatReg(floatReg, val, FloatRegFile::SingleWidth); 804 } 805 806 Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) 807 { 808 return floatRegFile.setRegBits(floatReg, val, width); 809 } 810 811 Fault setFloatRegBits(int floatReg, const FloatRegBits &val) 812 { 813 //Use the "natural" width of a single float 814 return floatRegFile.setRegBits(floatReg, val, 815 FloatRegFile::SingleWidth); 816 } 817 818 IntReg readIntReg(int intReg) 819 { 820 return intRegFile.readReg(intReg); 821 } 822 823 Fault setIntReg(int intReg, const IntReg &val) 824 { 825 return intRegFile.setReg(intReg, val); 826 } 827 828 void serialize(std::ostream &os); 829 void unserialize(Checkpoint *cp, const std::string §ion); 830 831 public: 832 833 enum ContextParam 834 { 835 CONTEXT_CWP, 836 CONTEXT_GLOBALS 837 }; 838 typedef int ContextVal; 839 840 void changeContext(ContextParam param, ContextVal val) 841 { 842 switch(param) 843 { 844 case CONTEXT_CWP: 845 intRegFile.setCWP(val); 846 break; 847 case CONTEXT_GLOBALS: 848 intRegFile.setGlobals(val); 849 break; 850 default: 851 panic("Tried to set illegal context parameter in the SPARC regfile.\n"); 852 } 853 } 854 }; 855 856 void copyRegs(ExecContext *src, ExecContext *dest); 857 858 void copyMiscRegs(ExecContext *src, ExecContext *dest); 859 860 int InterruptLevel(uint64_t softint); 861 862} // namespace SparcISA 863 864#endif 865