base.isa (12234:78ece221f9f5) | base.isa (12275:4b4dd932c710) |
---|---|
1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright --- 14 unchanged lines hidden (view full) --- 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 | 1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright --- 14 unchanged lines hidden (view full) --- 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 |
31//////////////////////////////////////////////////////////////////// 32// 33// Base class for sparc instructions, and some support functions 34// 35 36output header {{ 37 38 union CondCodes 39 { 40 struct 41 { 42 uint8_t c:1; 43 uint8_t v:1; 44 uint8_t z:1; 45 uint8_t n:1; 46 }; 47 uint32_t bits; 48 }; 49 50 enum CondTest 51 { 52 Always=0x8, 53 Never=0x0, 54 NotEqual=0x9, 55 Equal=0x1, 56 Greater=0xA, 57 LessOrEqual=0x2, 58 GreaterOrEqual=0xB, 59 Less=0x3, 60 GreaterUnsigned=0xC, 61 LessOrEqualUnsigned=0x4, 62 CarryClear=0xD, 63 CarrySet=0x5, 64 Positive=0xE, 65 Negative=0x6, 66 OverflowClear=0xF, 67 OverflowSet=0x7 68 }; 69 70 enum FpCondTest 71 { 72 FAlways=0x8, 73 FNever=0x0, 74 FUnordered=0x7, 75 FGreater=0x6, 76 FUnorderedOrGreater=0x5, 77 FLess=0x4, 78 FUnorderedOrLess=0x3, 79 FLessOrGreater=0x2, 80 FNotEqual=0x1, 81 FEqual=0x9, 82 FUnorderedOrEqual=0xA, 83 FGreaterOrEqual=0xB, 84 FUnorderedOrGreaterOrEqual=0xC, 85 FLessOrEqual=0xD, 86 FUnorderedOrLessOrEqual=0xE, 87 FOrdered=0xF 88 }; 89 90 extern const char *CondTestAbbrev[]; 91 92 /** 93 * Base class for all SPARC static instructions. 94 */ 95 class SparcStaticInst : public StaticInst 96 { 97 protected: 98 // Constructor. 99 SparcStaticInst(const char *mnem, 100 ExtMachInst _machInst, OpClass __opClass) 101 : StaticInst(mnem, _machInst, __opClass) 102 { 103 } 104 105 std::string generateDisassembly(Addr pc, 106 const SymbolTable *symtab) const; 107 108 void printReg(std::ostream &os, RegId reg) const; 109 void printSrcReg(std::ostream &os, int reg) const; 110 void printDestReg(std::ostream &os, int reg) const; 111 112 void printRegArray(std::ostream &os, 113 const RegId indexArray[], int num) const; 114 115 void advancePC(SparcISA::PCState &pcState) const; 116 }; 117 118 bool passesFpCondition(uint32_t fcc, uint32_t condition); 119 120 bool passesCondition(uint32_t codes, uint32_t condition); 121 122 inline int64_t 123 sign_ext(uint64_t data, int origWidth) 124 { 125 int shiftAmount = 64 - origWidth; 126 return (((int64_t)data) << shiftAmount) >> shiftAmount; 127 } 128}}; 129 130output decoder {{ 131 132 const char *CondTestAbbrev[] = 133 { 134 "nev", // Never 135 "e", // Equal 136 "le", // Less or Equal 137 "l", // Less 138 "leu", // Less or Equal Unsigned 139 "c", // Carry set 140 "n", // Negative 141 "o", // Overflow set 142 "a", // Always 143 "ne", // Not Equal 144 "g", // Greater 145 "ge", // Greater or Equal 146 "gu", // Greater Unsigned 147 "cc", // Carry clear 148 "p", // Positive 149 "oc" // Overflow Clear 150 }; 151}}; 152 | |
153def template ROrImmDecode {{ 154 { 155 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 156 : (SparcStaticInst *)(new %(class_name)s(machInst))); 157 } 158}}; 159 160output header {{ --- 77 unchanged lines hidden (view full) --- 238 rString += rOrImmMatch.group("typeQual") 239 iString = rOrImmMatch.group("iNum") 240 orig_code = code 241 code = matcher.sub('Rs' + rString, orig_code) 242 imm_code = matcher.sub('imm', orig_code) 243 return (True, code, imm_code, rString, iString) 244}}; 245 | 31def template ROrImmDecode {{ 32 { 33 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 34 : (SparcStaticInst *)(new %(class_name)s(machInst))); 35 } 36}}; 37 38output header {{ --- 77 unchanged lines hidden (view full) --- 116 rString += rOrImmMatch.group("typeQual") 117 iString = rOrImmMatch.group("iNum") 118 orig_code = code 119 code = matcher.sub('Rs' + rString, orig_code) 120 imm_code = matcher.sub('imm', orig_code) 121 return (True, code, imm_code, rString, iString) 122}}; 123 |
246output decoder {{ 247 248 inline void printMnemonic(std::ostream &os, const char * mnemonic) 249 { 250 ccprintf(os, "\t%s ", mnemonic); 251 } 252 253 void SparcStaticInst::printRegArray(std::ostream &os, 254 const RegId indexArray[], int num) const 255 { 256 if (num <= 0) 257 return; 258 printReg(os, indexArray[0]); 259 for (int x = 1; x < num; x++) { 260 os << ", "; 261 printReg(os, indexArray[x]); 262 } 263 } 264 265 void 266 SparcStaticInst::advancePC(SparcISA::PCState &pcState) const 267 { 268 pcState.advance(); 269 } 270 271 void 272 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const 273 { 274 if (_numSrcRegs > reg) 275 printReg(os, _srcRegIdx[reg]); 276 } 277 278 void 279 SparcStaticInst::printDestReg(std::ostream &os, int reg) const 280 { 281 if (_numDestRegs > reg) 282 printReg(os, _destRegIdx[reg]); 283 } 284 285 void 286 SparcStaticInst::printReg(std::ostream &os, RegId reg) const 287 { 288 const int MaxGlobal = 8; 289 const int MaxOutput = 16; 290 const int MaxLocal = 24; 291 const int MaxInput = 32; 292 const int MaxMicroReg = 40; 293 RegIndex reg_idx = reg.index(); 294 if (reg.isIntReg()) { 295 // If we used a register from the next or previous window, 296 // take out the offset. 297 while (reg_idx >= MaxMicroReg) 298 reg_idx -= MaxMicroReg; 299 if (reg_idx == FramePointerReg) 300 ccprintf(os, "%%fp"); 301 else if (reg_idx == StackPointerReg) 302 ccprintf(os, "%%sp"); 303 else if (reg_idx < MaxGlobal) 304 ccprintf(os, "%%g%d", reg_idx); 305 else if (reg_idx < MaxOutput) 306 ccprintf(os, "%%o%d", reg_idx - MaxGlobal); 307 else if (reg_idx < MaxLocal) 308 ccprintf(os, "%%l%d", reg_idx - MaxOutput); 309 else if (reg_idx < MaxInput) 310 ccprintf(os, "%%i%d", reg_idx - MaxLocal); 311 else if (reg_idx < MaxMicroReg) 312 ccprintf(os, "%%u%d", reg_idx - MaxInput); 313 // The fake int regs that are really control regs 314 else { 315 switch (reg_idx - MaxMicroReg) { 316 case 1: 317 ccprintf(os, "%%y"); 318 break; 319 case 2: 320 ccprintf(os, "%%ccr"); 321 break; 322 case 3: 323 ccprintf(os, "%%cansave"); 324 break; 325 case 4: 326 ccprintf(os, "%%canrestore"); 327 break; 328 case 5: 329 ccprintf(os, "%%cleanwin"); 330 break; 331 case 6: 332 ccprintf(os, "%%otherwin"); 333 break; 334 case 7: 335 ccprintf(os, "%%wstate"); 336 break; 337 } 338 } 339 } else if (reg.isFloatReg()) { 340 ccprintf(os, "%%f%d", reg_idx); 341 } else { 342 switch (reg_idx) { 343 case MISCREG_ASI: 344 ccprintf(os, "%%asi"); 345 break; 346 case MISCREG_FPRS: 347 ccprintf(os, "%%fprs"); 348 break; 349 case MISCREG_PCR: 350 ccprintf(os, "%%pcr"); 351 break; 352 case MISCREG_PIC: 353 ccprintf(os, "%%pic"); 354 break; 355 case MISCREG_GSR: 356 ccprintf(os, "%%gsr"); 357 break; 358 case MISCREG_SOFTINT: 359 ccprintf(os, "%%softint"); 360 break; 361 case MISCREG_SOFTINT_SET: 362 ccprintf(os, "%%softint_set"); 363 break; 364 case MISCREG_SOFTINT_CLR: 365 ccprintf(os, "%%softint_clr"); 366 break; 367 case MISCREG_TICK_CMPR: 368 ccprintf(os, "%%tick_cmpr"); 369 break; 370 case MISCREG_STICK: 371 ccprintf(os, "%%stick"); 372 break; 373 case MISCREG_STICK_CMPR: 374 ccprintf(os, "%%stick_cmpr"); 375 break; 376 case MISCREG_TPC: 377 ccprintf(os, "%%tpc"); 378 break; 379 case MISCREG_TNPC: 380 ccprintf(os, "%%tnpc"); 381 break; 382 case MISCREG_TSTATE: 383 ccprintf(os, "%%tstate"); 384 break; 385 case MISCREG_TT: 386 ccprintf(os, "%%tt"); 387 break; 388 case MISCREG_TICK: 389 ccprintf(os, "%%tick"); 390 break; 391 case MISCREG_TBA: 392 ccprintf(os, "%%tba"); 393 break; 394 case MISCREG_PSTATE: 395 ccprintf(os, "%%pstate"); 396 break; 397 case MISCREG_TL: 398 ccprintf(os, "%%tl"); 399 break; 400 case MISCREG_PIL: 401 ccprintf(os, "%%pil"); 402 break; 403 case MISCREG_CWP: 404 ccprintf(os, "%%cwp"); 405 break; 406 case MISCREG_GL: 407 ccprintf(os, "%%gl"); 408 break; 409 case MISCREG_HPSTATE: 410 ccprintf(os, "%%hpstate"); 411 break; 412 case MISCREG_HTSTATE: 413 ccprintf(os, "%%htstate"); 414 break; 415 case MISCREG_HINTP: 416 ccprintf(os, "%%hintp"); 417 break; 418 case MISCREG_HTBA: 419 ccprintf(os, "%%htba"); 420 break; 421 case MISCREG_HSTICK_CMPR: 422 ccprintf(os, "%%hstick_cmpr"); 423 break; 424 case MISCREG_HVER: 425 ccprintf(os, "%%hver"); 426 break; 427 case MISCREG_STRAND_STS_REG: 428 ccprintf(os, "%%strand_sts_reg"); 429 break; 430 case MISCREG_FSR: 431 ccprintf(os, "%%fsr"); 432 break; 433 default: 434 ccprintf(os, "%%ctrl%d", reg_idx); 435 } 436 } 437 } 438 439 std::string 440 SparcStaticInst::generateDisassembly(Addr pc, 441 const SymbolTable *symtab) const 442 { 443 std::stringstream ss; 444 445 printMnemonic(ss, mnemonic); 446 447 // just print the first two source regs... if there's 448 // a third one, it's a read-modify-write dest (Rc), 449 // e.g. for CMOVxx 450 if (_numSrcRegs > 0) 451 printReg(ss, _srcRegIdx[0]); 452 if (_numSrcRegs > 1) { 453 ss << ","; 454 printReg(ss, _srcRegIdx[1]); 455 } 456 457 // just print the first dest... if there's a second one, 458 // it's generally implicit 459 if (_numDestRegs > 0) { 460 if (_numSrcRegs > 0) 461 ss << ","; 462 printReg(ss, _destRegIdx[0]); 463 } 464 465 return ss.str(); 466 } 467 468 bool 469 passesFpCondition(uint32_t fcc, uint32_t condition) 470 { 471 bool u = (fcc == 3); 472 bool g = (fcc == 2); 473 bool l = (fcc == 1); 474 bool e = (fcc == 0); 475 switch (condition) { 476 case FAlways: 477 return 1; 478 case FNever: 479 return 0; 480 case FUnordered: 481 return u; 482 case FGreater: 483 return g; 484 case FUnorderedOrGreater: 485 return u || g; 486 case FLess: 487 return l; 488 case FUnorderedOrLess: 489 return u || l; 490 case FLessOrGreater: 491 return l || g; 492 case FNotEqual: 493 return l || g || u; 494 case FEqual: 495 return e; 496 case FUnorderedOrEqual: 497 return u || e; 498 case FGreaterOrEqual: 499 return g || e; 500 case FUnorderedOrGreaterOrEqual: 501 return u || g || e; 502 case FLessOrEqual: 503 return l || e; 504 case FUnorderedOrLessOrEqual: 505 return u || l || e; 506 case FOrdered: 507 return e || l || g; 508 } 509 panic("Tried testing condition nonexistant " 510 "condition code %d", condition); 511 } 512 513 bool 514 passesCondition(uint32_t codes, uint32_t condition) 515 { 516 CondCodes condCodes; 517 condCodes.bits = 0; 518 condCodes.c = codes & 0x1 ? 1 : 0; 519 condCodes.v = codes & 0x2 ? 1 : 0; 520 condCodes.z = codes & 0x4 ? 1 : 0; 521 condCodes.n = codes & 0x8 ? 1 : 0; 522 523 switch (condition) { 524 case Always: 525 return true; 526 case Never: 527 return false; 528 case NotEqual: 529 return !condCodes.z; 530 case Equal: 531 return condCodes.z; 532 case Greater: 533 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 534 case LessOrEqual: 535 return condCodes.z | (condCodes.n ^ condCodes.v); 536 case GreaterOrEqual: 537 return !(condCodes.n ^ condCodes.v); 538 case Less: 539 return (condCodes.n ^ condCodes.v); 540 case GreaterUnsigned: 541 return !(condCodes.c | condCodes.z); 542 case LessOrEqualUnsigned: 543 return (condCodes.c | condCodes.z); 544 case CarryClear: 545 return !condCodes.c; 546 case CarrySet: 547 return condCodes.c; 548 case Positive: 549 return !condCodes.n; 550 case Negative: 551 return condCodes.n; 552 case OverflowClear: 553 return !condCodes.v; 554 case OverflowSet: 555 return condCodes.v; 556 } 557 panic("Tried testing condition nonexistant " 558 "condition code %d", condition); 559 } 560}}; 561 | |
562output exec {{ 563 /// Check "FP enabled" machine status bit. Called when executing any FP 564 /// instruction. 565 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled 566 /// if not. Non-full-system mode: always returns NoFault. 567 static inline Fault 568 checkFpEnableFault(ExecContext *xc) 569 { 570 if (FullSystem) { 571 PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE); 572 if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) { 573 return NoFault; 574 } else { 575 return std::make_shared<FpDisabled>(); 576 } 577 } else { 578 return NoFault; 579 } 580 } | 124output exec {{ 125 /// Check "FP enabled" machine status bit. Called when executing any FP 126 /// instruction. 127 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled 128 /// if not. Non-full-system mode: always returns NoFault. 129 static inline Fault 130 checkFpEnableFault(ExecContext *xc) 131 { 132 if (FullSystem) { 133 PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE); 134 if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) { 135 return NoFault; 136 } else { 137 return std::make_shared<FpDisabled>(); 138 } 139 } else { 140 return NoFault; 141 } 142 } |
143 |
|
581 static inline Fault 582 checkVecEnableFault(ExecContext *xc) 583 { 584 return std::make_shared<VecDisabled>(); 585 } 586}}; 587 588 | 144 static inline Fault 145 checkVecEnableFault(ExecContext *xc) 146 { 147 return std::make_shared<VecDisabled>(); 148 } 149}}; 150 151 |