decoder.cc revision 9024:5851586f399c
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 "cpu/thread_context.hh" 37#include "debug/Decoder.hh" 38 39namespace X86ISA 40{ 41void Decoder::doReset() 42{ 43 origPC = basePC + offset; 44 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); 45 emi.rex = 0; 46 emi.legacy = 0; 47 emi.opcode.num = 0; 48 emi.opcode.op = 0; 49 emi.opcode.prefixA = emi.opcode.prefixB = 0; 50 51 immediateCollected = 0; 52 emi.immediate = 0; 53 emi.displacement = 0; 54 emi.dispSize = 0; 55 56 emi.modRM = 0; 57 emi.sib = 0; 58 m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 59 emi.mode.mode = m5Reg.mode; 60 emi.mode.submode = m5Reg.submode; 61} 62 63void Decoder::process() 64{ 65 //This function drives the decoder state machine. 66 67 //Some sanity checks. You shouldn't try to process more bytes if 68 //there aren't any, and you shouldn't overwrite an already 69 //decoder ExtMachInst. 70 assert(!outOfBytes); 71 assert(!instDone); 72 73 //While there's still something to do... 74 while(!instDone && !outOfBytes) 75 { 76 uint8_t nextByte = getNextByte(); 77 switch(state) 78 { 79 case ResetState: 80 doReset(); 81 state = PrefixState; 82 case PrefixState: 83 state = doPrefixState(nextByte); 84 break; 85 case OpcodeState: 86 state = doOpcodeState(nextByte); 87 break; 88 case ModRMState: 89 state = doModRMState(nextByte); 90 break; 91 case SIBState: 92 state = doSIBState(nextByte); 93 break; 94 case DisplacementState: 95 state = doDisplacementState(); 96 break; 97 case ImmediateState: 98 state = doImmediateState(); 99 break; 100 case ErrorState: 101 panic("Went to the error state in the decoder.\n"); 102 default: 103 panic("Unrecognized state! %d\n", state); 104 } 105 } 106} 107 108//Either get a prefix and record it in the ExtMachInst, or send the 109//state machine on to get the opcode(s). 110Decoder::State Decoder::doPrefixState(uint8_t nextByte) 111{ 112 uint8_t prefix = Prefixes[nextByte]; 113 State nextState = PrefixState; 114 // REX prefixes are only recognized in 64 bit mode. 115 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 116 prefix = 0; 117 if (prefix) 118 consumeByte(); 119 switch(prefix) 120 { 121 //Operand size override prefixes 122 case OperandSizeOverride: 123 DPRINTF(Decoder, "Found operand size override prefix.\n"); 124 emi.legacy.op = true; 125 break; 126 case AddressSizeOverride: 127 DPRINTF(Decoder, "Found address size override prefix.\n"); 128 emi.legacy.addr = true; 129 break; 130 //Segment override prefixes 131 case CSOverride: 132 case DSOverride: 133 case ESOverride: 134 case FSOverride: 135 case GSOverride: 136 case SSOverride: 137 DPRINTF(Decoder, "Found segment override.\n"); 138 emi.legacy.seg = prefix; 139 break; 140 case Lock: 141 DPRINTF(Decoder, "Found lock prefix.\n"); 142 emi.legacy.lock = true; 143 break; 144 case Rep: 145 DPRINTF(Decoder, "Found rep prefix.\n"); 146 emi.legacy.rep = true; 147 break; 148 case Repne: 149 DPRINTF(Decoder, "Found repne prefix.\n"); 150 emi.legacy.repne = true; 151 break; 152 case RexPrefix: 153 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 154 emi.rex = nextByte; 155 break; 156 case 0: 157 nextState = OpcodeState; 158 break; 159 default: 160 panic("Unrecognized prefix %#x\n", nextByte); 161 } 162 return nextState; 163} 164 165//Load all the opcodes (currently up to 2) and then figure out 166//what immediate and/or ModRM is needed. 167Decoder::State Decoder::doOpcodeState(uint8_t nextByte) 168{ 169 State nextState = ErrorState; 170 emi.opcode.num++; 171 //We can't handle 3+ byte opcodes right now 172 assert(emi.opcode.num < 4); 173 consumeByte(); 174 if(emi.opcode.num == 1 && nextByte == 0x0f) 175 { 176 nextState = OpcodeState; 177 DPRINTF(Decoder, "Found two byte opcode.\n"); 178 emi.opcode.prefixA = nextByte; 179 } 180 else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A)) 181 { 182 nextState = OpcodeState; 183 DPRINTF(Decoder, "Found three byte opcode.\n"); 184 emi.opcode.prefixB = nextByte; 185 } 186 else 187 { 188 DPRINTF(Decoder, "Found opcode %#x.\n", nextByte); 189 emi.opcode.op = nextByte; 190 191 //Figure out the effective operand size. This can be overriden to 192 //a fixed value at the decoder level. 193 int logOpSize; 194 if (emi.rex.w) 195 logOpSize = 3; // 64 bit operand size 196 else if (emi.legacy.op) 197 logOpSize = m5Reg.altOp; 198 else 199 logOpSize = m5Reg.defOp; 200 201 //Set the actual op size 202 emi.opSize = 1 << logOpSize; 203 204 //Figure out the effective address size. This can be overriden to 205 //a fixed value at the decoder level. 206 int logAddrSize; 207 if(emi.legacy.addr) 208 logAddrSize = m5Reg.altAddr; 209 else 210 logAddrSize = m5Reg.defAddr; 211 212 //Set the actual address size 213 emi.addrSize = 1 << logAddrSize; 214 215 //Figure out the effective stack width. This can be overriden to 216 //a fixed value at the decoder level. 217 emi.stackSize = 1 << m5Reg.stack; 218 219 //Figure out how big of an immediate we'll retreive based 220 //on the opcode. 221 int immType = ImmediateType[emi.opcode.num - 1][nextByte]; 222 if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3) 223 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 224 else 225 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 226 227 //Determine what to expect next 228 if (UsesModRM[emi.opcode.num - 1][nextByte]) { 229 nextState = ModRMState; 230 } else { 231 if(immediateSize) { 232 nextState = ImmediateState; 233 } else { 234 instDone = true; 235 nextState = ResetState; 236 } 237 } 238 } 239 return nextState; 240} 241 242//Get the ModRM byte and determine what displacement, if any, there is. 243//Also determine whether or not to get the SIB byte, displacement, or 244//immediate next. 245Decoder::State Decoder::doModRMState(uint8_t nextByte) 246{ 247 State nextState = ErrorState; 248 ModRM modRM; 249 modRM = nextByte; 250 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); 251 if (m5Reg.defOp == 1) { 252 //figure out 16 bit displacement size 253 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 254 displacementSize = 2; 255 else if (modRM.mod == 1) 256 displacementSize = 1; 257 else 258 displacementSize = 0; 259 } else { 260 //figure out 32/64 bit displacement size 261 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 262 displacementSize = 4; 263 else if (modRM.mod == 1) 264 displacementSize = 1; 265 else 266 displacementSize = 0; 267 } 268 269 // The "test" instruction in group 3 needs an immediate, even though 270 // the other instructions with the same actual opcode don't. 271 if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) { 272 if (emi.opcode.op == 0xF6) 273 immediateSize = 1; 274 else if (emi.opcode.op == 0xF7) 275 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 276 } 277 278 //If there's an SIB, get that next. 279 //There is no SIB in 16 bit mode. 280 if (modRM.rm == 4 && modRM.mod != 3) { 281 // && in 32/64 bit mode) 282 nextState = SIBState; 283 } else if(displacementSize) { 284 nextState = DisplacementState; 285 } else if(immediateSize) { 286 nextState = ImmediateState; 287 } else { 288 instDone = true; 289 nextState = ResetState; 290 } 291 //The ModRM byte is consumed no matter what 292 consumeByte(); 293 emi.modRM = modRM; 294 return nextState; 295} 296 297//Get the SIB byte. We don't do anything with it at this point, other 298//than storing it in the ExtMachInst. Determine if we need to get a 299//displacement or immediate next. 300Decoder::State Decoder::doSIBState(uint8_t nextByte) 301{ 302 State nextState = ErrorState; 303 emi.sib = nextByte; 304 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 305 consumeByte(); 306 if (emi.modRM.mod == 0 && emi.sib.base == 5) 307 displacementSize = 4; 308 if (displacementSize) { 309 nextState = DisplacementState; 310 } else if(immediateSize) { 311 nextState = ImmediateState; 312 } else { 313 instDone = true; 314 nextState = ResetState; 315 } 316 return nextState; 317} 318 319//Gather up the displacement, or at least as much of it 320//as we can get. 321Decoder::State Decoder::doDisplacementState() 322{ 323 State nextState = ErrorState; 324 325 getImmediate(immediateCollected, 326 emi.displacement, 327 displacementSize); 328 329 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 330 displacementSize, immediateCollected); 331 332 if(displacementSize == immediateCollected) { 333 //Reset this for other immediates. 334 immediateCollected = 0; 335 //Sign extend the displacement 336 switch(displacementSize) 337 { 338 case 1: 339 emi.displacement = sext<8>(emi.displacement); 340 break; 341 case 2: 342 emi.displacement = sext<16>(emi.displacement); 343 break; 344 case 4: 345 emi.displacement = sext<32>(emi.displacement); 346 break; 347 default: 348 panic("Undefined displacement size!\n"); 349 } 350 DPRINTF(Decoder, "Collected displacement %#x.\n", 351 emi.displacement); 352 if(immediateSize) { 353 nextState = ImmediateState; 354 } else { 355 instDone = true; 356 nextState = ResetState; 357 } 358 359 emi.dispSize = displacementSize; 360 } 361 else 362 nextState = DisplacementState; 363 return nextState; 364} 365 366//Gather up the immediate, or at least as much of it 367//as we can get 368Decoder::State Decoder::doImmediateState() 369{ 370 State nextState = ErrorState; 371 372 getImmediate(immediateCollected, 373 emi.immediate, 374 immediateSize); 375 376 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 377 immediateSize, immediateCollected); 378 379 if(immediateSize == immediateCollected) 380 { 381 //Reset this for other immediates. 382 immediateCollected = 0; 383 384 //XXX Warning! The following is an observed pattern and might 385 //not always be true! 386 387 //Instructions which use 64 bit operands but 32 bit immediates 388 //need to have the immediate sign extended to 64 bits. 389 //Instructions which use true 64 bit immediates won't be 390 //affected, and instructions that use true 32 bit immediates 391 //won't notice. 392 switch(immediateSize) 393 { 394 case 4: 395 emi.immediate = sext<32>(emi.immediate); 396 break; 397 case 1: 398 emi.immediate = sext<8>(emi.immediate); 399 } 400 401 DPRINTF(Decoder, "Collected immediate %#x.\n", 402 emi.immediate); 403 instDone = true; 404 nextState = ResetState; 405 } 406 else 407 nextState = ImmediateState; 408 return nextState; 409} 410 411DecodeCache::InstMap Decoder::instMap; 412DecodeCache::AddrMap<StaticInstPtr> Decoder::decodePages; 413 414StaticInstPtr 415Decoder::decode(ExtMachInst mach_inst, Addr addr) 416{ 417 StaticInstPtr &si = decodePages.lookup(addr); 418 if (si && (si->machInst == mach_inst)) 419 return si; 420 421 DecodeCache::InstMap::iterator iter = instMap.find(mach_inst); 422 if (iter != instMap.end()) { 423 si = iter->second; 424 return si; 425 } 426 427 si = decodeInst(mach_inst); 428 instMap[mach_inst] = si; 429 return si; 430} 431 432} 433