1/* 2 * Copyright (c) 2011 Google 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#include "arch/x86/decoder.hh"
| 1/* 2 * Copyright (c) 2011 Google 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#include "arch/x86/decoder.hh"
|
32#include "arch/x86/regs/misc.hh" 33#include "base/misc.hh" 34#include "base/trace.hh" 35#include "base/types.hh" 36#include "debug/Decoder.hh" 37 38namespace X86ISA 39{ 40 41Decoder::State 42Decoder::doResetState() 43{ 44 origPC = basePC + offset; 45 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); 46 instBytes = &decodePages->lookup(origPC); 47 chunkIdx = 0; 48 49 emi.rex = 0; 50 emi.legacy = 0; 51 emi.vex = 0; 52 53 emi.opcode.type = BadOpcode; 54 emi.opcode.op = 0; 55 56 immediateCollected = 0; 57 emi.immediate = 0; 58 emi.displacement = 0; 59 emi.dispSize = 0; 60 61 emi.modRM = 0; 62 emi.sib = 0; 63 64 if (instBytes->si) { 65 return FromCacheState; 66 } else { 67 instBytes->chunks.clear(); 68 return PrefixState; 69 } 70} 71 72void 73Decoder::process() 74{ 75 //This function drives the decoder state machine. 76 77 //Some sanity checks. You shouldn't try to process more bytes if 78 //there aren't any, and you shouldn't overwrite an already 79 //decoder ExtMachInst. 80 assert(!outOfBytes); 81 assert(!instDone); 82 83 if (state == ResetState) 84 state = doResetState(); 85 if (state == FromCacheState) { 86 state = doFromCacheState(); 87 } else { 88 instBytes->chunks.push_back(fetchChunk); 89 } 90 91 //While there's still something to do... 92 while (!instDone && !outOfBytes) { 93 uint8_t nextByte = getNextByte(); 94 switch (state) { 95 case PrefixState: 96 state = doPrefixState(nextByte); 97 break; 98 99 case TwoByteVexState: 100 state = doTwoByteVexState(nextByte); 101 break; 102 103 case ThreeByteVexFirstState: 104 state = doThreeByteVexFirstState(nextByte); 105 break; 106 107 case ThreeByteVexSecondState: 108 state = doThreeByteVexSecondState(nextByte); 109 break; 110 111 case OneByteOpcodeState: 112 state = doOneByteOpcodeState(nextByte); 113 break; 114 case TwoByteOpcodeState: 115 state = doTwoByteOpcodeState(nextByte); 116 break; 117 case ThreeByte0F38OpcodeState: 118 state = doThreeByte0F38OpcodeState(nextByte); 119 break; 120 case ThreeByte0F3AOpcodeState: 121 state = doThreeByte0F3AOpcodeState(nextByte); 122 break; 123 case ModRMState: 124 state = doModRMState(nextByte); 125 break; 126 case SIBState: 127 state = doSIBState(nextByte); 128 break; 129 case DisplacementState: 130 state = doDisplacementState(); 131 break; 132 case ImmediateState: 133 state = doImmediateState(); 134 break; 135 case ErrorState: 136 panic("Went to the error state in the decoder.\n"); 137 default: 138 panic("Unrecognized state! %d\n", state); 139 } 140 } 141} 142 143Decoder::State 144Decoder::doFromCacheState() 145{ 146 DPRINTF(Decoder, "Looking at cache state.\n"); 147 if ((fetchChunk & instBytes->masks[chunkIdx]) != 148 instBytes->chunks[chunkIdx]) { 149 DPRINTF(Decoder, "Decode cache miss.\n"); 150 // The chached chunks didn't match what was fetched. Fall back to the 151 // predecoder. 152 instBytes->chunks[chunkIdx] = fetchChunk; 153 instBytes->chunks.resize(chunkIdx + 1); 154 instBytes->si = NULL; 155 chunkIdx = 0; 156 fetchChunk = instBytes->chunks[0]; 157 offset = origPC % sizeof(MachInst); 158 basePC = origPC - offset; 159 return PrefixState; 160 } else if (chunkIdx == instBytes->chunks.size() - 1) { 161 // We matched the cache, so use its value. 162 instDone = true; 163 offset = instBytes->lastOffset; 164 if (offset == sizeof(MachInst)) 165 outOfBytes = true; 166 return ResetState; 167 } else { 168 // We matched so far, but need to check more chunks. 169 chunkIdx++; 170 outOfBytes = true; 171 return FromCacheState; 172 } 173} 174 175//Either get a prefix and record it in the ExtMachInst, or send the 176//state machine on to get the opcode(s). 177Decoder::State 178Decoder::doPrefixState(uint8_t nextByte) 179{ 180 uint8_t prefix = Prefixes[nextByte]; 181 State nextState = PrefixState; 182 // REX prefixes are only recognized in 64 bit mode. 183 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 184 prefix = 0; 185 if (prefix) 186 consumeByte(); 187 switch(prefix) 188 { 189 //Operand size override prefixes 190 case OperandSizeOverride: 191 DPRINTF(Decoder, "Found operand size override prefix.\n"); 192 emi.legacy.op = true; 193 break; 194 case AddressSizeOverride: 195 DPRINTF(Decoder, "Found address size override prefix.\n"); 196 emi.legacy.addr = true; 197 break; 198 //Segment override prefixes 199 case CSOverride: 200 case DSOverride: 201 case ESOverride: 202 case FSOverride: 203 case GSOverride: 204 case SSOverride: 205 DPRINTF(Decoder, "Found segment override.\n"); 206 emi.legacy.seg = prefix; 207 break; 208 case Lock: 209 DPRINTF(Decoder, "Found lock prefix.\n"); 210 emi.legacy.lock = true; 211 break; 212 case Rep: 213 DPRINTF(Decoder, "Found rep prefix.\n"); 214 emi.legacy.rep = true; 215 break; 216 case Repne: 217 DPRINTF(Decoder, "Found repne prefix.\n"); 218 emi.legacy.repne = true; 219 break; 220 case RexPrefix: 221 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 222 emi.rex = nextByte; 223 break; 224 225 case Vex2Prefix: 226 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte); 227 emi.vex.zero = nextByte; 228 nextState = TwoByteVexState; 229 break; 230 231 case Vex3Prefix: 232 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte); 233 emi.vex.zero = nextByte; 234 nextState = ThreeByteVexFirstState; 235 break; 236 237 case 0: 238 nextState = OneByteOpcodeState; 239 break; 240 241 default: 242 panic("Unrecognized prefix %#x\n", nextByte); 243 } 244 return nextState; 245} 246 247Decoder::State 248Decoder::doTwoByteVexState(uint8_t nextByte) 249{ 250 assert(emi.vex.zero == 0xc5); 251 consumeByte(); 252 TwoByteVex tbe = 0; 253 tbe.first = nextByte; 254 255 emi.vex.first.r = tbe.first.r; 256 emi.vex.first.x = 1; 257 emi.vex.first.b = 1; 258 emi.vex.first.map_select = 1; 259 260 emi.vex.second.w = 0; 261 emi.vex.second.vvvv = tbe.first.vvvv; 262 emi.vex.second.l = tbe.first.l; 263 emi.vex.second.pp = tbe.first.pp; 264 265 emi.opcode.type = Vex; 266 return OneByteOpcodeState; 267} 268 269Decoder::State 270Decoder::doThreeByteVexFirstState(uint8_t nextByte) 271{ 272 consumeByte(); 273 emi.vex.first = nextByte; 274 return ThreeByteVexSecondState; 275} 276 277Decoder::State 278Decoder::doThreeByteVexSecondState(uint8_t nextByte) 279{ 280 consumeByte(); 281 emi.vex.second = nextByte; 282 emi.opcode.type = Vex; 283 return OneByteOpcodeState; 284} 285 286// Load the first opcode byte. Determine if there are more opcode bytes, and 287// if not, what immediate and/or ModRM is needed. 288Decoder::State 289Decoder::doOneByteOpcodeState(uint8_t nextByte) 290{ 291 State nextState = ErrorState; 292 consumeByte(); 293 294 if (emi.vex.zero != 0) { 295 DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte); 296 emi.opcode.op = nextByte; 297 const uint8_t opcode_map = emi.vex.first.map_select; 298 nextState = processExtendedOpcode(ImmediateTypeVex[opcode_map]); 299 } else if (nextByte == 0x0f) { 300 nextState = TwoByteOpcodeState; 301 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 302 } else { 303 DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte); 304 emi.opcode.type = OneByteOpcode; 305 emi.opcode.op = nextByte; 306 307 nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 308 nextByte >= 0xA0 && nextByte <= 0xA3); 309 } 310 return nextState; 311} 312 313// Load the second opcode byte. Determine if there are more opcode bytes, and 314// if not, what immediate and/or ModRM is needed. 315Decoder::State 316Decoder::doTwoByteOpcodeState(uint8_t nextByte) 317{ 318 State nextState = ErrorState; 319 consumeByte(); 320 if (nextByte == 0x38) { 321 nextState = ThreeByte0F38OpcodeState; 322 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 323 } else if (nextByte == 0x3a) { 324 nextState = ThreeByte0F3AOpcodeState; 325 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 326 } else { 327 DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte); 328 emi.opcode.type = TwoByteOpcode; 329 emi.opcode.op = nextByte; 330 331 nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte); 332 } 333 return nextState; 334} 335 336// Load the third opcode byte and determine what immediate and/or ModRM is 337// needed. 338Decoder::State 339Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte) 340{ 341 consumeByte(); 342 343 DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte); 344 emi.opcode.type = ThreeByte0F38Opcode; 345 emi.opcode.op = nextByte; 346 347 return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38); 348} 349 350// Load the third opcode byte and determine what immediate and/or ModRM is 351// needed. 352Decoder::State 353Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte) 354{ 355 consumeByte(); 356 357 DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte); 358 emi.opcode.type = ThreeByte0F3AOpcode; 359 emi.opcode.op = nextByte; 360 361 return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A); 362} 363 364// Generic opcode processing which determines the immediate size, and whether 365// or not there's a modrm byte. 366Decoder::State 367Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable, 368 bool addrSizedImm) 369{ 370 State nextState = ErrorState; 371 const uint8_t opcode = emi.opcode.op; 372 373 //Figure out the effective operand size. This can be overriden to 374 //a fixed value at the decoder level. 375 int logOpSize; 376 if (emi.rex.w) 377 logOpSize = 3; // 64 bit operand size 378 else if (emi.legacy.op) 379 logOpSize = altOp; 380 else 381 logOpSize = defOp; 382 383 //Set the actual op size 384 emi.opSize = 1 << logOpSize; 385 386 //Figure out the effective address size. This can be overriden to 387 //a fixed value at the decoder level. 388 int logAddrSize; 389 if (emi.legacy.addr) 390 logAddrSize = altAddr; 391 else 392 logAddrSize = defAddr; 393 394 //Set the actual address size 395 emi.addrSize = 1 << logAddrSize; 396 397 //Figure out the effective stack width. This can be overriden to 398 //a fixed value at the decoder level. 399 emi.stackSize = 1 << stack; 400 401 //Figure out how big of an immediate we'll retreive based 402 //on the opcode. 403 int immType = immTable[opcode]; 404 if (addrSizedImm) 405 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 406 else 407 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 408 409 //Determine what to expect next 410 if (modrmTable[opcode]) { 411 nextState = ModRMState; 412 } else { 413 if (immediateSize) { 414 nextState = ImmediateState; 415 } else { 416 instDone = true; 417 nextState = ResetState; 418 } 419 } 420 return nextState; 421} 422 423Decoder::State 424Decoder::processExtendedOpcode(ByteTable &immTable) 425{ 426 //Figure out the effective operand size. This can be overriden to 427 //a fixed value at the decoder level. 428 int logOpSize; 429 if (emi.vex.second.w) 430 logOpSize = 3; // 64 bit operand size 431 else if (emi.vex.second.pp == 1) 432 logOpSize = altOp; 433 else 434 logOpSize = defOp; 435 436 //Set the actual op size 437 emi.opSize = 1 << logOpSize; 438 439 //Figure out the effective address size. This can be overriden to 440 //a fixed value at the decoder level. 441 int logAddrSize; 442 if (emi.legacy.addr) 443 logAddrSize = altAddr; 444 else 445 logAddrSize = defAddr; 446 447 //Set the actual address size 448 emi.addrSize = 1 << logAddrSize; 449 450 //Figure out the effective stack width. This can be overriden to 451 //a fixed value at the decoder level. 452 emi.stackSize = 1 << stack; 453 454 //Figure out how big of an immediate we'll retreive based 455 //on the opcode. 456 const uint8_t opcode = emi.opcode.op; 457 458 if (emi.vex.zero == 0xc5 || emi.vex.zero == 0xc4) { 459 int immType = immTable[opcode]; 460 // Assume 64-bit mode; 461 immediateSize = SizeTypeToSize[2][immType]; 462 } 463 464 if (opcode == 0x77) { 465 instDone = true; 466 return ResetState; 467 } 468 return ModRMState; 469} 470 471//Get the ModRM byte and determine what displacement, if any, there is. 472//Also determine whether or not to get the SIB byte, displacement, or 473//immediate next. 474Decoder::State 475Decoder::doModRMState(uint8_t nextByte) 476{ 477 State nextState = ErrorState; 478 ModRM modRM = nextByte; 479 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); 480 if (defOp == 1) { 481 //figure out 16 bit displacement size 482 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 483 displacementSize = 2; 484 else if (modRM.mod == 1) 485 displacementSize = 1; 486 else 487 displacementSize = 0; 488 } else { 489 //figure out 32/64 bit displacement size 490 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 491 displacementSize = 4; 492 else if (modRM.mod == 1) 493 displacementSize = 1; 494 else 495 displacementSize = 0; 496 } 497 498 // The "test" instruction in group 3 needs an immediate, even though 499 // the other instructions with the same actual opcode don't. 500 if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) { 501 if (emi.opcode.op == 0xF6) 502 immediateSize = 1; 503 else if (emi.opcode.op == 0xF7) 504 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 505 } 506 507 //If there's an SIB, get that next. 508 //There is no SIB in 16 bit mode. 509 if (modRM.rm == 4 && modRM.mod != 3) { 510 // && in 32/64 bit mode) 511 nextState = SIBState; 512 } else if (displacementSize) { 513 nextState = DisplacementState; 514 } else if (immediateSize) { 515 nextState = ImmediateState; 516 } else { 517 instDone = true; 518 nextState = ResetState; 519 } 520 //The ModRM byte is consumed no matter what 521 consumeByte(); 522 emi.modRM = modRM; 523 return nextState; 524} 525 526//Get the SIB byte. We don't do anything with it at this point, other 527//than storing it in the ExtMachInst. Determine if we need to get a 528//displacement or immediate next. 529Decoder::State 530Decoder::doSIBState(uint8_t nextByte) 531{ 532 State nextState = ErrorState; 533 emi.sib = nextByte; 534 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 535 consumeByte(); 536 if (emi.modRM.mod == 0 && emi.sib.base == 5) 537 displacementSize = 4; 538 if (displacementSize) { 539 nextState = DisplacementState; 540 } else if (immediateSize) { 541 nextState = ImmediateState; 542 } else { 543 instDone = true; 544 nextState = ResetState; 545 } 546 return nextState; 547} 548 549//Gather up the displacement, or at least as much of it 550//as we can get. 551Decoder::State 552Decoder::doDisplacementState() 553{ 554 State nextState = ErrorState; 555 556 getImmediate(immediateCollected, 557 emi.displacement, 558 displacementSize); 559 560 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 561 displacementSize, immediateCollected); 562 563 if (displacementSize == immediateCollected) { 564 //Reset this for other immediates. 565 immediateCollected = 0; 566 //Sign extend the displacement 567 switch(displacementSize) 568 { 569 case 1: 570 emi.displacement = sext<8>(emi.displacement); 571 break; 572 case 2: 573 emi.displacement = sext<16>(emi.displacement); 574 break; 575 case 4: 576 emi.displacement = sext<32>(emi.displacement); 577 break; 578 default: 579 panic("Undefined displacement size!\n"); 580 } 581 DPRINTF(Decoder, "Collected displacement %#x.\n", 582 emi.displacement); 583 if (immediateSize) { 584 nextState = ImmediateState; 585 } else { 586 instDone = true; 587 nextState = ResetState; 588 } 589 590 emi.dispSize = displacementSize; 591 } 592 else 593 nextState = DisplacementState; 594 return nextState; 595} 596 597//Gather up the immediate, or at least as much of it 598//as we can get 599Decoder::State 600Decoder::doImmediateState() 601{ 602 State nextState = ErrorState; 603 604 getImmediate(immediateCollected, 605 emi.immediate, 606 immediateSize); 607 608 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 609 immediateSize, immediateCollected); 610 611 if (immediateSize == immediateCollected) 612 { 613 //Reset this for other immediates. 614 immediateCollected = 0; 615 616 //XXX Warning! The following is an observed pattern and might 617 //not always be true! 618 619 //Instructions which use 64 bit operands but 32 bit immediates 620 //need to have the immediate sign extended to 64 bits. 621 //Instructions which use true 64 bit immediates won't be 622 //affected, and instructions that use true 32 bit immediates 623 //won't notice. 624 switch(immediateSize) 625 { 626 case 4: 627 emi.immediate = sext<32>(emi.immediate); 628 break; 629 case 1: 630 emi.immediate = sext<8>(emi.immediate); 631 } 632 633 DPRINTF(Decoder, "Collected immediate %#x.\n", 634 emi.immediate); 635 instDone = true; 636 nextState = ResetState; 637 } 638 else 639 nextState = ImmediateState; 640 return nextState; 641} 642 643Decoder::InstBytes Decoder::dummy; 644Decoder::InstCacheMap Decoder::instCacheMap; 645 646StaticInstPtr 647Decoder::decode(ExtMachInst mach_inst, Addr addr) 648{ 649 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst); 650 if (iter != instMap->end()) 651 return iter->second; 652 653 StaticInstPtr si = decodeInst(mach_inst); 654 (*instMap)[mach_inst] = si; 655 return si; 656} 657 658StaticInstPtr 659Decoder::decode(PCState &nextPC) 660{ 661 if (!instDone) 662 return NULL; 663 instDone = false; 664 updateNPC(nextPC); 665 666 StaticInstPtr &si = instBytes->si; 667 if (si) 668 return si; 669 670 // We didn't match in the AddrMap, but we still populated an entry. Fix 671 // up its byte masks. 672 const int chunkSize = sizeof(MachInst); 673 674 instBytes->lastOffset = offset; 675 676 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize; 677 Addr firstOffset = origPC - firstBasePC; 678 Addr totalSize = instBytes->lastOffset - firstOffset + 679 (instBytes->chunks.size() - 1) * chunkSize; 680 int start = firstOffset; 681 instBytes->masks.clear(); 682 683 while (totalSize) { 684 int end = start + totalSize; 685 end = (chunkSize < end) ? chunkSize : end; 686 int size = end - start; 687 int idx = instBytes->masks.size(); 688 689 MachInst maskVal = mask(size * 8) << (start * 8); 690 assert(maskVal); 691 692 instBytes->masks.push_back(maskVal); 693 instBytes->chunks[idx] &= instBytes->masks[idx]; 694 totalSize -= size; 695 start = 0; 696 } 697 698 si = decode(emi, origPC); 699 return si; 700} 701 702}
| 33#include "arch/x86/regs/misc.hh" 34#include "base/misc.hh" 35#include "base/trace.hh" 36#include "base/types.hh" 37#include "debug/Decoder.hh" 38 39namespace X86ISA 40{ 41 42Decoder::State 43Decoder::doResetState() 44{ 45 origPC = basePC + offset; 46 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); 47 instBytes = &decodePages->lookup(origPC); 48 chunkIdx = 0; 49 50 emi.rex = 0; 51 emi.legacy = 0; 52 emi.vex = 0; 53 54 emi.opcode.type = BadOpcode; 55 emi.opcode.op = 0; 56 57 immediateCollected = 0; 58 emi.immediate = 0; 59 emi.displacement = 0; 60 emi.dispSize = 0; 61 62 emi.modRM = 0; 63 emi.sib = 0; 64 65 if (instBytes->si) { 66 return FromCacheState; 67 } else { 68 instBytes->chunks.clear(); 69 return PrefixState; 70 } 71} 72 73void 74Decoder::process() 75{ 76 //This function drives the decoder state machine. 77 78 //Some sanity checks. You shouldn't try to process more bytes if 79 //there aren't any, and you shouldn't overwrite an already 80 //decoder ExtMachInst. 81 assert(!outOfBytes); 82 assert(!instDone); 83 84 if (state == ResetState) 85 state = doResetState(); 86 if (state == FromCacheState) { 87 state = doFromCacheState(); 88 } else { 89 instBytes->chunks.push_back(fetchChunk); 90 } 91 92 //While there's still something to do... 93 while (!instDone && !outOfBytes) { 94 uint8_t nextByte = getNextByte(); 95 switch (state) { 96 case PrefixState: 97 state = doPrefixState(nextByte); 98 break; 99 100 case TwoByteVexState: 101 state = doTwoByteVexState(nextByte); 102 break; 103 104 case ThreeByteVexFirstState: 105 state = doThreeByteVexFirstState(nextByte); 106 break; 107 108 case ThreeByteVexSecondState: 109 state = doThreeByteVexSecondState(nextByte); 110 break; 111 112 case OneByteOpcodeState: 113 state = doOneByteOpcodeState(nextByte); 114 break; 115 case TwoByteOpcodeState: 116 state = doTwoByteOpcodeState(nextByte); 117 break; 118 case ThreeByte0F38OpcodeState: 119 state = doThreeByte0F38OpcodeState(nextByte); 120 break; 121 case ThreeByte0F3AOpcodeState: 122 state = doThreeByte0F3AOpcodeState(nextByte); 123 break; 124 case ModRMState: 125 state = doModRMState(nextByte); 126 break; 127 case SIBState: 128 state = doSIBState(nextByte); 129 break; 130 case DisplacementState: 131 state = doDisplacementState(); 132 break; 133 case ImmediateState: 134 state = doImmediateState(); 135 break; 136 case ErrorState: 137 panic("Went to the error state in the decoder.\n"); 138 default: 139 panic("Unrecognized state! %d\n", state); 140 } 141 } 142} 143 144Decoder::State 145Decoder::doFromCacheState() 146{ 147 DPRINTF(Decoder, "Looking at cache state.\n"); 148 if ((fetchChunk & instBytes->masks[chunkIdx]) != 149 instBytes->chunks[chunkIdx]) { 150 DPRINTF(Decoder, "Decode cache miss.\n"); 151 // The chached chunks didn't match what was fetched. Fall back to the 152 // predecoder. 153 instBytes->chunks[chunkIdx] = fetchChunk; 154 instBytes->chunks.resize(chunkIdx + 1); 155 instBytes->si = NULL; 156 chunkIdx = 0; 157 fetchChunk = instBytes->chunks[0]; 158 offset = origPC % sizeof(MachInst); 159 basePC = origPC - offset; 160 return PrefixState; 161 } else if (chunkIdx == instBytes->chunks.size() - 1) { 162 // We matched the cache, so use its value. 163 instDone = true; 164 offset = instBytes->lastOffset; 165 if (offset == sizeof(MachInst)) 166 outOfBytes = true; 167 return ResetState; 168 } else { 169 // We matched so far, but need to check more chunks. 170 chunkIdx++; 171 outOfBytes = true; 172 return FromCacheState; 173 } 174} 175 176//Either get a prefix and record it in the ExtMachInst, or send the 177//state machine on to get the opcode(s). 178Decoder::State 179Decoder::doPrefixState(uint8_t nextByte) 180{ 181 uint8_t prefix = Prefixes[nextByte]; 182 State nextState = PrefixState; 183 // REX prefixes are only recognized in 64 bit mode. 184 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 185 prefix = 0; 186 if (prefix) 187 consumeByte(); 188 switch(prefix) 189 { 190 //Operand size override prefixes 191 case OperandSizeOverride: 192 DPRINTF(Decoder, "Found operand size override prefix.\n"); 193 emi.legacy.op = true; 194 break; 195 case AddressSizeOverride: 196 DPRINTF(Decoder, "Found address size override prefix.\n"); 197 emi.legacy.addr = true; 198 break; 199 //Segment override prefixes 200 case CSOverride: 201 case DSOverride: 202 case ESOverride: 203 case FSOverride: 204 case GSOverride: 205 case SSOverride: 206 DPRINTF(Decoder, "Found segment override.\n"); 207 emi.legacy.seg = prefix; 208 break; 209 case Lock: 210 DPRINTF(Decoder, "Found lock prefix.\n"); 211 emi.legacy.lock = true; 212 break; 213 case Rep: 214 DPRINTF(Decoder, "Found rep prefix.\n"); 215 emi.legacy.rep = true; 216 break; 217 case Repne: 218 DPRINTF(Decoder, "Found repne prefix.\n"); 219 emi.legacy.repne = true; 220 break; 221 case RexPrefix: 222 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 223 emi.rex = nextByte; 224 break; 225 226 case Vex2Prefix: 227 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte); 228 emi.vex.zero = nextByte; 229 nextState = TwoByteVexState; 230 break; 231 232 case Vex3Prefix: 233 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte); 234 emi.vex.zero = nextByte; 235 nextState = ThreeByteVexFirstState; 236 break; 237 238 case 0: 239 nextState = OneByteOpcodeState; 240 break; 241 242 default: 243 panic("Unrecognized prefix %#x\n", nextByte); 244 } 245 return nextState; 246} 247 248Decoder::State 249Decoder::doTwoByteVexState(uint8_t nextByte) 250{ 251 assert(emi.vex.zero == 0xc5); 252 consumeByte(); 253 TwoByteVex tbe = 0; 254 tbe.first = nextByte; 255 256 emi.vex.first.r = tbe.first.r; 257 emi.vex.first.x = 1; 258 emi.vex.first.b = 1; 259 emi.vex.first.map_select = 1; 260 261 emi.vex.second.w = 0; 262 emi.vex.second.vvvv = tbe.first.vvvv; 263 emi.vex.second.l = tbe.first.l; 264 emi.vex.second.pp = tbe.first.pp; 265 266 emi.opcode.type = Vex; 267 return OneByteOpcodeState; 268} 269 270Decoder::State 271Decoder::doThreeByteVexFirstState(uint8_t nextByte) 272{ 273 consumeByte(); 274 emi.vex.first = nextByte; 275 return ThreeByteVexSecondState; 276} 277 278Decoder::State 279Decoder::doThreeByteVexSecondState(uint8_t nextByte) 280{ 281 consumeByte(); 282 emi.vex.second = nextByte; 283 emi.opcode.type = Vex; 284 return OneByteOpcodeState; 285} 286 287// Load the first opcode byte. Determine if there are more opcode bytes, and 288// if not, what immediate and/or ModRM is needed. 289Decoder::State 290Decoder::doOneByteOpcodeState(uint8_t nextByte) 291{ 292 State nextState = ErrorState; 293 consumeByte(); 294 295 if (emi.vex.zero != 0) { 296 DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte); 297 emi.opcode.op = nextByte; 298 const uint8_t opcode_map = emi.vex.first.map_select; 299 nextState = processExtendedOpcode(ImmediateTypeVex[opcode_map]); 300 } else if (nextByte == 0x0f) { 301 nextState = TwoByteOpcodeState; 302 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 303 } else { 304 DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte); 305 emi.opcode.type = OneByteOpcode; 306 emi.opcode.op = nextByte; 307 308 nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 309 nextByte >= 0xA0 && nextByte <= 0xA3); 310 } 311 return nextState; 312} 313 314// Load the second opcode byte. Determine if there are more opcode bytes, and 315// if not, what immediate and/or ModRM is needed. 316Decoder::State 317Decoder::doTwoByteOpcodeState(uint8_t nextByte) 318{ 319 State nextState = ErrorState; 320 consumeByte(); 321 if (nextByte == 0x38) { 322 nextState = ThreeByte0F38OpcodeState; 323 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 324 } else if (nextByte == 0x3a) { 325 nextState = ThreeByte0F3AOpcodeState; 326 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); 327 } else { 328 DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte); 329 emi.opcode.type = TwoByteOpcode; 330 emi.opcode.op = nextByte; 331 332 nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte); 333 } 334 return nextState; 335} 336 337// Load the third opcode byte and determine what immediate and/or ModRM is 338// needed. 339Decoder::State 340Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte) 341{ 342 consumeByte(); 343 344 DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte); 345 emi.opcode.type = ThreeByte0F38Opcode; 346 emi.opcode.op = nextByte; 347 348 return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38); 349} 350 351// Load the third opcode byte and determine what immediate and/or ModRM is 352// needed. 353Decoder::State 354Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte) 355{ 356 consumeByte(); 357 358 DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte); 359 emi.opcode.type = ThreeByte0F3AOpcode; 360 emi.opcode.op = nextByte; 361 362 return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A); 363} 364 365// Generic opcode processing which determines the immediate size, and whether 366// or not there's a modrm byte. 367Decoder::State 368Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable, 369 bool addrSizedImm) 370{ 371 State nextState = ErrorState; 372 const uint8_t opcode = emi.opcode.op; 373 374 //Figure out the effective operand size. This can be overriden to 375 //a fixed value at the decoder level. 376 int logOpSize; 377 if (emi.rex.w) 378 logOpSize = 3; // 64 bit operand size 379 else if (emi.legacy.op) 380 logOpSize = altOp; 381 else 382 logOpSize = defOp; 383 384 //Set the actual op size 385 emi.opSize = 1 << logOpSize; 386 387 //Figure out the effective address size. This can be overriden to 388 //a fixed value at the decoder level. 389 int logAddrSize; 390 if (emi.legacy.addr) 391 logAddrSize = altAddr; 392 else 393 logAddrSize = defAddr; 394 395 //Set the actual address size 396 emi.addrSize = 1 << logAddrSize; 397 398 //Figure out the effective stack width. This can be overriden to 399 //a fixed value at the decoder level. 400 emi.stackSize = 1 << stack; 401 402 //Figure out how big of an immediate we'll retreive based 403 //on the opcode. 404 int immType = immTable[opcode]; 405 if (addrSizedImm) 406 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 407 else 408 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 409 410 //Determine what to expect next 411 if (modrmTable[opcode]) { 412 nextState = ModRMState; 413 } else { 414 if (immediateSize) { 415 nextState = ImmediateState; 416 } else { 417 instDone = true; 418 nextState = ResetState; 419 } 420 } 421 return nextState; 422} 423 424Decoder::State 425Decoder::processExtendedOpcode(ByteTable &immTable) 426{ 427 //Figure out the effective operand size. This can be overriden to 428 //a fixed value at the decoder level. 429 int logOpSize; 430 if (emi.vex.second.w) 431 logOpSize = 3; // 64 bit operand size 432 else if (emi.vex.second.pp == 1) 433 logOpSize = altOp; 434 else 435 logOpSize = defOp; 436 437 //Set the actual op size 438 emi.opSize = 1 << logOpSize; 439 440 //Figure out the effective address size. This can be overriden to 441 //a fixed value at the decoder level. 442 int logAddrSize; 443 if (emi.legacy.addr) 444 logAddrSize = altAddr; 445 else 446 logAddrSize = defAddr; 447 448 //Set the actual address size 449 emi.addrSize = 1 << logAddrSize; 450 451 //Figure out the effective stack width. This can be overriden to 452 //a fixed value at the decoder level. 453 emi.stackSize = 1 << stack; 454 455 //Figure out how big of an immediate we'll retreive based 456 //on the opcode. 457 const uint8_t opcode = emi.opcode.op; 458 459 if (emi.vex.zero == 0xc5 || emi.vex.zero == 0xc4) { 460 int immType = immTable[opcode]; 461 // Assume 64-bit mode; 462 immediateSize = SizeTypeToSize[2][immType]; 463 } 464 465 if (opcode == 0x77) { 466 instDone = true; 467 return ResetState; 468 } 469 return ModRMState; 470} 471 472//Get the ModRM byte and determine what displacement, if any, there is. 473//Also determine whether or not to get the SIB byte, displacement, or 474//immediate next. 475Decoder::State 476Decoder::doModRMState(uint8_t nextByte) 477{ 478 State nextState = ErrorState; 479 ModRM modRM = nextByte; 480 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); 481 if (defOp == 1) { 482 //figure out 16 bit displacement size 483 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 484 displacementSize = 2; 485 else if (modRM.mod == 1) 486 displacementSize = 1; 487 else 488 displacementSize = 0; 489 } else { 490 //figure out 32/64 bit displacement size 491 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 492 displacementSize = 4; 493 else if (modRM.mod == 1) 494 displacementSize = 1; 495 else 496 displacementSize = 0; 497 } 498 499 // The "test" instruction in group 3 needs an immediate, even though 500 // the other instructions with the same actual opcode don't. 501 if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) { 502 if (emi.opcode.op == 0xF6) 503 immediateSize = 1; 504 else if (emi.opcode.op == 0xF7) 505 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 506 } 507 508 //If there's an SIB, get that next. 509 //There is no SIB in 16 bit mode. 510 if (modRM.rm == 4 && modRM.mod != 3) { 511 // && in 32/64 bit mode) 512 nextState = SIBState; 513 } else if (displacementSize) { 514 nextState = DisplacementState; 515 } else if (immediateSize) { 516 nextState = ImmediateState; 517 } else { 518 instDone = true; 519 nextState = ResetState; 520 } 521 //The ModRM byte is consumed no matter what 522 consumeByte(); 523 emi.modRM = modRM; 524 return nextState; 525} 526 527//Get the SIB byte. We don't do anything with it at this point, other 528//than storing it in the ExtMachInst. Determine if we need to get a 529//displacement or immediate next. 530Decoder::State 531Decoder::doSIBState(uint8_t nextByte) 532{ 533 State nextState = ErrorState; 534 emi.sib = nextByte; 535 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 536 consumeByte(); 537 if (emi.modRM.mod == 0 && emi.sib.base == 5) 538 displacementSize = 4; 539 if (displacementSize) { 540 nextState = DisplacementState; 541 } else if (immediateSize) { 542 nextState = ImmediateState; 543 } else { 544 instDone = true; 545 nextState = ResetState; 546 } 547 return nextState; 548} 549 550//Gather up the displacement, or at least as much of it 551//as we can get. 552Decoder::State 553Decoder::doDisplacementState() 554{ 555 State nextState = ErrorState; 556 557 getImmediate(immediateCollected, 558 emi.displacement, 559 displacementSize); 560 561 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 562 displacementSize, immediateCollected); 563 564 if (displacementSize == immediateCollected) { 565 //Reset this for other immediates. 566 immediateCollected = 0; 567 //Sign extend the displacement 568 switch(displacementSize) 569 { 570 case 1: 571 emi.displacement = sext<8>(emi.displacement); 572 break; 573 case 2: 574 emi.displacement = sext<16>(emi.displacement); 575 break; 576 case 4: 577 emi.displacement = sext<32>(emi.displacement); 578 break; 579 default: 580 panic("Undefined displacement size!\n"); 581 } 582 DPRINTF(Decoder, "Collected displacement %#x.\n", 583 emi.displacement); 584 if (immediateSize) { 585 nextState = ImmediateState; 586 } else { 587 instDone = true; 588 nextState = ResetState; 589 } 590 591 emi.dispSize = displacementSize; 592 } 593 else 594 nextState = DisplacementState; 595 return nextState; 596} 597 598//Gather up the immediate, or at least as much of it 599//as we can get 600Decoder::State 601Decoder::doImmediateState() 602{ 603 State nextState = ErrorState; 604 605 getImmediate(immediateCollected, 606 emi.immediate, 607 immediateSize); 608 609 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 610 immediateSize, immediateCollected); 611 612 if (immediateSize == immediateCollected) 613 { 614 //Reset this for other immediates. 615 immediateCollected = 0; 616 617 //XXX Warning! The following is an observed pattern and might 618 //not always be true! 619 620 //Instructions which use 64 bit operands but 32 bit immediates 621 //need to have the immediate sign extended to 64 bits. 622 //Instructions which use true 64 bit immediates won't be 623 //affected, and instructions that use true 32 bit immediates 624 //won't notice. 625 switch(immediateSize) 626 { 627 case 4: 628 emi.immediate = sext<32>(emi.immediate); 629 break; 630 case 1: 631 emi.immediate = sext<8>(emi.immediate); 632 } 633 634 DPRINTF(Decoder, "Collected immediate %#x.\n", 635 emi.immediate); 636 instDone = true; 637 nextState = ResetState; 638 } 639 else 640 nextState = ImmediateState; 641 return nextState; 642} 643 644Decoder::InstBytes Decoder::dummy; 645Decoder::InstCacheMap Decoder::instCacheMap; 646 647StaticInstPtr 648Decoder::decode(ExtMachInst mach_inst, Addr addr) 649{ 650 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst); 651 if (iter != instMap->end()) 652 return iter->second; 653 654 StaticInstPtr si = decodeInst(mach_inst); 655 (*instMap)[mach_inst] = si; 656 return si; 657} 658 659StaticInstPtr 660Decoder::decode(PCState &nextPC) 661{ 662 if (!instDone) 663 return NULL; 664 instDone = false; 665 updateNPC(nextPC); 666 667 StaticInstPtr &si = instBytes->si; 668 if (si) 669 return si; 670 671 // We didn't match in the AddrMap, but we still populated an entry. Fix 672 // up its byte masks. 673 const int chunkSize = sizeof(MachInst); 674 675 instBytes->lastOffset = offset; 676 677 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize; 678 Addr firstOffset = origPC - firstBasePC; 679 Addr totalSize = instBytes->lastOffset - firstOffset + 680 (instBytes->chunks.size() - 1) * chunkSize; 681 int start = firstOffset; 682 instBytes->masks.clear(); 683 684 while (totalSize) { 685 int end = start + totalSize; 686 end = (chunkSize < end) ? chunkSize : end; 687 int size = end - start; 688 int idx = instBytes->masks.size(); 689 690 MachInst maskVal = mask(size * 8) << (start * 8); 691 assert(maskVal); 692 693 instBytes->masks.push_back(maskVal); 694 instBytes->chunks[idx] &= instBytes->masks[idx]; 695 totalSize -= size; 696 start = 0; 697 } 698 699 si = decode(emi, origPC); 700 return si; 701} 702 703}
|