registers.hh revision 2459
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 29#ifndef __ARCH_SPARC_REGFILE_HH__ 30#define __ARCH_SPARC_REGFILE_HH__ 31 32#include "arch/sparc/faults.hh" 33#include "sim/byteswap.hh" 34#include "sim/host.hh" 35 36class Checkpoint; 37 38namespace SparcISA 39{ 40 41 typedef uint8_t RegIndex; 42 43 // Maximum trap level 44 const int MaxTL = 4; 45 46 //For right now, let's pretend the register file is flat 47 typedef IntReg IntRegFile[NumIntRegs]; 48 49 typedef float float32_t; 50 typedef double float64_t; 51 //FIXME long double refers to a 10 byte float, rather than a 52 //16 byte float as required. This data type may have to be emulated. 53 typedef double float128_t; 54 55 class FloatRegFile 56 { 57 protected: 58 //Since the floating point registers overlap each other, 59 //A generic storage space is used. The float to be returned is 60 //pulled from the appropriate section of this region. 61 char regSpace[32 * 64]; 62 63 static const int SingleWidth = 32; 64 static const int DoubleWidth = 64; 65 static const int QuadWidth = 128; 66 67 public: 68 69 FloatReg readReg(int floatReg, int width) 70 { 71 //In each of these cases, we have to copy the value into a temporary 72 //variable. This is because we may otherwise try to access an 73 //unaligned portion of memory. 74 switch(width) 75 { 76 case SingleWidth: 77 float32_t result32; 78 memcpy(&result32, regSpace + 4 * floatReg, width); 79 return htog(result32); 80 case DoubleWidth: 81 float64_t result64; 82 memcpy(&result64, regSpace + 4 * floatReg, width); 83 return htog(result64); 84 case QuadWidth: 85 float128_t result128; 86 memcpy(&result128, regSpace + 4 * floatReg, width); 87 return htog(result128); 88 default: 89 panic("Attempted to read a %d bit floating point register!", width); 90 } 91 } 92 93 FloatReg readReg(int floatReg) 94 { 95 //Use the "natural" width of a single float 96 return readReg(floatReg, SingleWidth); 97 } 98 99 FloatRegBits readRegBits(int floatReg, int width) 100 { 101 //In each of these cases, we have to copy the value into a temporary 102 //variable. This is because we may otherwise try to access an 103 //unaligned portion of memory. 104 switch(width) 105 { 106 case SingleWidth: 107 uint32_t result32; 108 memcpy(&result32, regSpace + 4 * floatReg, width); 109 return htog(result32); 110 case DoubleWidth: 111 uint64_t result64; 112 memcpy(&result64, regSpace + 4 * floatReg, width); 113 return htog(result64); 114 case QuadWidth: 115 uint64_t result128; 116 memcpy(&result128, regSpace + 4 * floatReg, width); 117 return htog(result128); 118 default: 119 panic("Attempted to read a %d bit floating point register!", width); 120 } 121 } 122 123 FloatRegBits readRegBits(int floatReg) 124 { 125 //Use the "natural" width of a single float 126 return readRegBits(floatReg, SingleWidth); 127 } 128 129 Fault setReg(int floatReg, const FloatReg &val, int width) 130 { 131 //In each of these cases, we have to copy the value into a temporary 132 //variable. This is because we may otherwise try to access an 133 //unaligned portion of memory. 134 switch(width) 135 { 136 case SingleWidth: 137 uint32_t result32 = gtoh((uint32_t)val); 138 memcpy(regSpace + 4 * floatReg, &result32, width); 139 case DoubleWidth: 140 uint64_t result64 = gtoh((uint64_t)val); 141 memcpy(regSpace + 4 * floatReg, &result64, width); 142 case QuadWidth: 143 uint64_t result128 = gtoh((uint64_t)val); 144 memcpy(regSpace + 4 * floatReg, &result128, width); 145 default: 146 panic("Attempted to read a %d bit floating point register!", width); 147 } 148 return NoFault; 149 } 150 151 Fault setReg(int floatReg, const FloatReg &val) 152 { 153 //Use the "natural" width of a single float 154 return setReg(floatReg, val, SingleWidth); 155 } 156 157 Fault setRegBits(int floatReg, const FloatRegBits &val, int width) 158 { 159 //In each of these cases, we have to copy the value into a temporary 160 //variable. This is because we may otherwise try to access an 161 //unaligned portion of memory. 162 switch(width) 163 { 164 case SingleWidth: 165 uint32_t result32 = gtoh((uint32_t)val); 166 memcpy(regSpace + 4 * floatReg, &result32, width); 167 case DoubleWidth: 168 uint64_t result64 = gtoh((uint64_t)val); 169 memcpy(regSpace + 4 * floatReg, &result64, width); 170 case QuadWidth: 171 uint64_t result128 = gtoh((uint64_t)val); 172 memcpy(regSpace + 4 * floatReg, &result128, width); 173 default: 174 panic("Attempted to read a %d bit floating point register!", width); 175 } 176 return NoFault; 177 } 178 179 Fault setRegBits(int floatReg, const FloatRegBits &val) 180 { 181 //Use the "natural" width of a single float 182 return setReg(floatReg, val, SingleWidth); 183 } 184 185 void serialize(std::ostream &os); 186 187 void unserialize(Checkpoint *cp, const std::string §ion); 188 }; 189 190 enum MiscRegIndex 191 { 192 MISCREG_PSTATE, 193 MISCREG_PSTATE_AG, 194 MISCREG_PSTATE_IE, 195 MISCREG_PSTATE_PRIV, 196 MISCREG_PSTATE_AM, 197 MISCREG_PSTATE_PEF, 198 MISCREG_PSTATE_RED, 199 MISCREG_PSTATE_MM, 200 MISCREG_PSTATE_TLE, 201 MISCREG_PSTATE_CLE, 202 MISCREG_TBA, 203 MISCREG_Y, 204 MISCREG_Y_VALUE, 205 MISCREG_PIL, 206 MISCREG_CWP, 207 MISCREG_TT_BASE, 208 MISCREG_TT_END = MISCREG_TT_BASE + MaxTL, 209 MISCREG_CCR, 210 MISCREG_CCR_ICC, 211 MISCREG_CCR_ICC_C, 212 MISCREG_CCR_ICC_V, 213 MISCREG_CCR_ICC_Z, 214 MISCREG_CCR_ICC_N, 215 MISCREG_CCR_XCC, 216 MISCREG_CCR_XCC_C, 217 MISCREG_CCR_XCC_V, 218 MISCREG_CCR_XCC_Z, 219 MISCREG_CCR_XCC_N, 220 MISCREG_ASI, 221 MISCREG_TL, 222 MISCREG_TPC_BASE, 223 MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL, 224 MISCREG_TNPC_BASE, 225 MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL, 226 MISCREG_TSTATE_BASE, 227 MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL, 228 MISCREG_TSTATE_CWP_BASE, 229 MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL, 230 MISCREG_TSTATE_PSTATE_BASE, 231 MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL, 232 MISCREG_TSTATE_ASI_BASE, 233 MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL, 234 MISCREG_TSTATE_CCR_BASE, 235 MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL, 236 MISCREG_TICK, 237 MISCREG_TICK_COUNTER, 238 MISCREG_TICK_NPT, 239 MISCREG_CANSAVE, 240 MISCREG_CANRESTORE, 241 MISCREG_OTHERWIN, 242 MISCREG_CLEANWIN, 243 MISCREG_WSTATE, 244 MISCREG_WSTATE_NORMAL, 245 MISCREG_WSTATE_OTHER, 246 MISCREG_VER, 247 MISCREG_VER_MAXWIN, 248 MISCREG_VER_MAXTL, 249 MISCREG_VER_MASK, 250 MISCREG_VER_IMPL, 251 MISCREG_VER_MANUF, 252 MISCREG_FSR, 253 MISCREG_FSR_CEXC, 254 MISCREG_FSR_CEXC_NXC, 255 MISCREG_FSR_CEXC_DZC, 256 MISCREG_FSR_CEXC_UFC, 257 MISCREG_FSR_CEXC_OFC, 258 MISCREG_FSR_CEXC_NVC, 259 MISCREG_FSR_AEXC, 260 MISCREG_FSR_AEXC_NXC, 261 MISCREG_FSR_AEXC_DZC, 262 MISCREG_FSR_AEXC_UFC, 263 MISCREG_FSR_AEXC_OFC, 264 MISCREG_FSR_AEXC_NVC, 265 MISCREG_FSR_FCC0, 266 MISCREG_FSR_QNE, 267 MISCREG_FSR_FTT, 268 MISCREG_FSR_VER, 269 MISCREG_FSR_NS, 270 MISCREG_FSR_TEM, 271 MISCREG_FSR_TEM_NXM, 272 MISCREG_FSR_TEM_DZM, 273 MISCREG_FSR_TEM_UFM, 274 MISCREG_FSR_TEM_OFM, 275 MISCREG_FSR_TEM_NVM, 276 MISCREG_FSR_RD, 277 MISCREG_FSR_FCC1, 278 MISCREG_FSR_FCC2, 279 MISCREG_FSR_FCC3, 280 MISCREG_FPRS, 281 MISCREG_FPRS_DL, 282 MISCREG_FPRS_DU, 283 MISCREG_FPRS_FEF, 284 numMiscRegs 285 }; 286 287 // The control registers, broken out into fields 288 class MiscRegFile 289 { 290 private: 291 union 292 { 293 uint16_t pstate; // Process State Register 294 struct 295 { 296 uint16_t ag:1; // Alternate Globals 297 uint16_t ie:1; // Interrupt enable 298 uint16_t priv:1; // Privelege mode 299 uint16_t am:1; // Address mask 300 uint16_t pef:1; // PSTATE enable floating-point 301 uint16_t red:1; // RED (reset, error, debug) state 302 uint16_t mm:2; // Memory Model 303 uint16_t tle:1; // Trap little-endian 304 uint16_t cle:1; // Current little-endian 305 } pstateFields; 306 }; 307 uint64_t tba; // Trap Base Address 308 union 309 { 310 uint64_t y; // Y (used in obsolete multiplication) 311 struct 312 { 313 uint64_t value:32; // The actual value stored in y 314 uint64_t :32; // reserved bits 315 } yFields; 316 }; 317 uint8_t pil; // Process Interrupt Register 318 uint8_t cwp; // Current Window Pointer 319 uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured 320 // on the previous level) 321 union 322 { 323 uint8_t ccr; // Condition Code Register 324 struct 325 { 326 union 327 { 328 uint8_t icc:4; // 32-bit condition codes 329 struct 330 { 331 uint8_t c:1; // Carry 332 uint8_t v:1; // Overflow 333 uint8_t z:1; // Zero 334 uint8_t n:1; // Negative 335 } iccFields; 336 }; 337 union 338 { 339 uint8_t xcc:4; // 64-bit condition codes 340 struct 341 { 342 uint8_t c:1; // Carry 343 uint8_t v:1; // Overflow 344 uint8_t z:1; // Zero 345 uint8_t n:1; // Negative 346 } xccFields; 347 }; 348 } ccrFields; 349 }; 350 uint8_t asi; // Address Space Identifier 351 uint8_t tl; // Trap Level 352 uint64_t tpc[MaxTL]; // Trap Program Counter (value from 353 // previous trap level) 354 uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from 355 // previous trap level) 356 union 357 { 358 uint64_t tstate[MaxTL]; // Trap State 359 struct 360 { 361 //Values are from previous trap level 362 uint64_t cwp:5; // Current Window Pointer 363 uint64_t :2; // Reserved bits 364 uint64_t pstate:10; // Process State 365 uint64_t :6; // Reserved bits 366 uint64_t asi:8; // Address Space Identifier 367 uint64_t ccr:8; // Condition Code Register 368 } tstateFields[MaxTL]; 369 }; 370 union 371 { 372 uint64_t tick; // Hardware clock-tick counter 373 struct 374 { 375 uint64_t counter:63; // Clock-tick count 376 uint64_t npt:1; // Non-priveleged trap 377 } tickFields; 378 }; 379 uint8_t cansave; // Savable windows 380 uint8_t canrestore; // Restorable windows 381 uint8_t otherwin; // Other windows 382 uint8_t cleanwin; // Clean windows 383 union 384 { 385 uint8_t wstate; // Window State 386 struct 387 { 388 uint8_t normal:3; // Bits TT<4:2> are set to on a normal 389 // register window trap 390 uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" 391 // register window trap 392 } wstateFields; 393 }; 394 union 395 { 396 uint64_t ver; // Version 397 struct 398 { 399 uint64_t maxwin:5; // Max CWP value 400 uint64_t :2; // Reserved bits 401 uint64_t maxtl:8; // Maximum trap level 402 uint64_t :8; // Reserved bits 403 uint64_t mask:8; // Processor mask set revision number 404 uint64_t impl:16; // Implementation identification number 405 uint64_t manuf:16; // Manufacturer code 406 } verFields; 407 }; 408 union 409 { 410 uint64_t fsr; // Floating-Point State Register 411 struct 412 { 413 union 414 { 415 uint64_t cexc:5; // Current excpetion 416 struct 417 { 418 uint64_t nxc:1; // Inexact 419 uint64_t dzc:1; // Divide by zero 420 uint64_t ufc:1; // Underflow 421 uint64_t ofc:1; // Overflow 422 uint64_t nvc:1; // Invalid operand 423 } cexcFields; 424 }; 425 union 426 { 427 uint64_t aexc:5; // Accrued exception 428 struct 429 { 430 uint64_t nxc:1; // Inexact 431 uint64_t dzc:1; // Divide by zero 432 uint64_t ufc:1; // Underflow 433 uint64_t ofc:1; // Overflow 434 uint64_t nvc:1; // Invalid operand 435 } aexcFields; 436 }; 437 uint64_t fcc0:2; // Floating-Point condtion codes 438 uint64_t :1; // Reserved bits 439 uint64_t qne:1; // Deferred trap queue not empty 440 // with no queue, it should read 0 441 uint64_t ftt:3; // Floating-Point trap type 442 uint64_t ver:3; // Version (of the FPU) 443 uint64_t :2; // Reserved bits 444 uint64_t ns:1; // Nonstandard floating point 445 union 446 { 447 uint64_t tem:5; // Trap Enable Mask 448 struct 449 { 450 uint64_t nxm:1; // Inexact 451 uint64_t dzm:1; // Divide by zero 452 uint64_t ufm:1; // Underflow 453 uint64_t ofm:1; // Overflow 454 uint64_t nvm:1; // Invalid operand 455 } temFields; 456 }; 457 uint64_t :2; // Reserved bits 458 uint64_t rd:2; // Rounding direction 459 uint64_t fcc1:2; // Floating-Point condition codes 460 uint64_t fcc2:2; // Floating-Point condition codes 461 uint64_t fcc3:2; // Floating-Point condition codes 462 uint64_t :26; // Reserved bits 463 } fsrFields; 464 }; 465 union 466 { 467 uint8_t fprs; // Floating-Point Register State 468 struct 469 { 470 uint8_t dl:1; // Dirty lower 471 uint8_t du:1; // Dirty upper 472 uint8_t fef:1; // FPRS enable floating-Point 473 } fprsFields; 474 }; 475 476 public: 477 MiscReg readReg(int miscReg); 478 479 MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc); 480 481 Fault setReg(int miscReg, const MiscReg &val); 482 483 Fault setRegWithEffect(int miscReg, const MiscReg &val, 484 ExecContext *xc); 485 486 void serialize(std::ostream & os); 487 488 void unserialize(Checkpoint * cp, const std::string & section); 489 490 void copyMiscRegs(ExecContext * xc); 491 }; 492 493 typedef union 494 { 495 IntReg intreg; 496 FloatReg fpreg; 497 MiscReg ctrlreg; 498 } AnyReg; 499 500 struct RegFile 501 { 502 IntRegFile intRegFile; // (signed) integer register file 503 FloatRegFile floatRegFile; // floating point register file 504 MiscRegFile miscRegs; // control register file 505 506 Addr pc; // Program Counter 507 Addr npc; // Next Program Counter 508 Addr nnpc; 509 510 void serialize(std::ostream &os); 511 void unserialize(Checkpoint *cp, const std::string §ion); 512 }; 513 514} // namespace SparcISA 515 516#endif 517