decoder.cc (9024:5851586f399c) | decoder.cc (9376:270c9a75e91f) |
---|---|
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; --- 24 unchanged lines hidden (view full) --- 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{ | 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; --- 24 unchanged lines hidden (view full) --- 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() | 41 42Decoder::State 43Decoder::doResetState() |
42{ 43 origPC = basePC + offset; 44 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); | 44{ 45 origPC = basePC + offset; 46 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC); |
47 instBytes = &decodePages->lookup(origPC); 48 chunkIdx = 0; 49 |
|
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; | 50 emi.rex = 0; 51 emi.legacy = 0; 52 emi.opcode.num = 0; 53 emi.opcode.op = 0; 54 emi.opcode.prefixA = emi.opcode.prefixB = 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; |
58 m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 59 emi.mode.mode = m5Reg.mode; 60 emi.mode.submode = m5Reg.submode; | 63 64 if (instBytes->si) { 65 return FromCacheState; 66 } else { 67 instBytes->chunks.clear(); 68 return PrefixState; 69 } |
61} 62 | 70} 71 |
63void Decoder::process() | 72void 73Decoder::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 | 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 |
|
73 //While there's still something to do... | 91 //While there's still something to do... |
74 while(!instDone && !outOfBytes) 75 { | 92 while (!instDone && !outOfBytes) { |
76 uint8_t nextByte = getNextByte(); | 93 uint8_t nextByte = getNextByte(); |
77 switch(state) 78 { 79 case ResetState: 80 doReset(); 81 state = PrefixState; | 94 switch (state) { |
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); --- 10 unchanged lines hidden (view full) --- 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 | 95 case PrefixState: 96 state = doPrefixState(nextByte); 97 break; 98 case OpcodeState: 99 state = doOpcodeState(nextByte); 100 break; 101 case ModRMState: 102 state = doModRMState(nextByte); --- 10 unchanged lines hidden (view full) --- 113 case ErrorState: 114 panic("Went to the error state in the decoder.\n"); 115 default: 116 panic("Unrecognized state! %d\n", state); 117 } 118 } 119} 120 |
121Decoder::State 122Decoder::doFromCacheState() 123{ 124 DPRINTF(Decoder, "Looking at cache state.\n"); 125 if ((fetchChunk & instBytes->masks[chunkIdx]) != 126 instBytes->chunks[chunkIdx]) { 127 DPRINTF(Decoder, "Decode cache miss.\n"); 128 // The chached chunks didn't match what was fetched. Fall back to the 129 // predecoder. 130 instBytes->chunks[chunkIdx] = fetchChunk; 131 instBytes->chunks.resize(chunkIdx + 1); 132 instBytes->si = NULL; 133 chunkIdx = 0; 134 fetchChunk = instBytes->chunks[0]; 135 offset = origPC % sizeof(MachInst); 136 basePC = origPC - offset; 137 return PrefixState; 138 } else if (chunkIdx == instBytes->chunks.size() - 1) { 139 // We matched the cache, so use its value. 140 instDone = true; 141 offset = instBytes->lastOffset; 142 if (offset == sizeof(MachInst)) 143 outOfBytes = true; 144 return ResetState; 145 } else { 146 // We matched so far, but need to check more chunks. 147 chunkIdx++; 148 outOfBytes = true; 149 return FromCacheState; 150 } 151} 152 |
|
108//Either get a prefix and record it in the ExtMachInst, or send the 109//state machine on to get the opcode(s). | 153//Either get a prefix and record it in the ExtMachInst, or send the 154//state machine on to get the opcode(s). |
110Decoder::State Decoder::doPrefixState(uint8_t nextByte) | 155Decoder::State 156Decoder::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(); --- 40 unchanged lines hidden (view full) --- 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. | 157{ 158 uint8_t prefix = Prefixes[nextByte]; 159 State nextState = PrefixState; 160 // REX prefixes are only recognized in 64 bit mode. 161 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 162 prefix = 0; 163 if (prefix) 164 consumeByte(); --- 40 unchanged lines hidden (view full) --- 205 default: 206 panic("Unrecognized prefix %#x\n", nextByte); 207 } 208 return nextState; 209} 210 211//Load all the opcodes (currently up to 2) and then figure out 212//what immediate and/or ModRM is needed. |
167Decoder::State Decoder::doOpcodeState(uint8_t nextByte) | 213Decoder::State 214Decoder::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 { --- 13 unchanged lines hidden (view full) --- 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) | 215{ 216 State nextState = ErrorState; 217 emi.opcode.num++; 218 //We can't handle 3+ byte opcodes right now 219 assert(emi.opcode.num < 4); 220 consumeByte(); 221 if(emi.opcode.num == 1 && nextByte == 0x0f) 222 { --- 13 unchanged lines hidden (view full) --- 236 emi.opcode.op = nextByte; 237 238 //Figure out the effective operand size. This can be overriden to 239 //a fixed value at the decoder level. 240 int logOpSize; 241 if (emi.rex.w) 242 logOpSize = 3; // 64 bit operand size 243 else if (emi.legacy.op) |
197 logOpSize = m5Reg.altOp; | 244 logOpSize = altOp; |
198 else | 245 else |
199 logOpSize = m5Reg.defOp; | 246 logOpSize = 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) | 247 248 //Set the actual op size 249 emi.opSize = 1 << logOpSize; 250 251 //Figure out the effective address size. This can be overriden to 252 //a fixed value at the decoder level. 253 int logAddrSize; 254 if(emi.legacy.addr) |
208 logAddrSize = m5Reg.altAddr; | 255 logAddrSize = altAddr; |
209 else | 256 else |
210 logAddrSize = m5Reg.defAddr; | 257 logAddrSize = 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. | 258 259 //Set the actual address size 260 emi.addrSize = 1 << logAddrSize; 261 262 //Figure out the effective stack width. This can be overriden to 263 //a fixed value at the decoder level. |
217 emi.stackSize = 1 << m5Reg.stack; | 264 emi.stackSize = 1 << 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]; --- 11 unchanged lines hidden (view full) --- 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. | 265 266 //Figure out how big of an immediate we'll retreive based 267 //on the opcode. 268 int immType = ImmediateType[emi.opcode.num - 1][nextByte]; 269 if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3) 270 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 271 else 272 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; --- 11 unchanged lines hidden (view full) --- 284 } 285 } 286 return nextState; 287} 288 289//Get the ModRM byte and determine what displacement, if any, there is. 290//Also determine whether or not to get the SIB byte, displacement, or 291//immediate next. |
245Decoder::State Decoder::doModRMState(uint8_t nextByte) | 292Decoder::State 293Decoder::doModRMState(uint8_t nextByte) |
246{ 247 State nextState = ErrorState; 248 ModRM modRM; 249 modRM = nextByte; 250 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); | 294{ 295 State nextState = ErrorState; 296 ModRM modRM; 297 modRM = nextByte; 298 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte); |
251 if (m5Reg.defOp == 1) { | 299 if (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 { --- 32 unchanged lines hidden (view full) --- 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. | 300 //figure out 16 bit displacement size 301 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 302 displacementSize = 2; 303 else if (modRM.mod == 1) 304 displacementSize = 1; 305 else 306 displacementSize = 0; 307 } else { --- 32 unchanged lines hidden (view full) --- 340 consumeByte(); 341 emi.modRM = modRM; 342 return nextState; 343} 344 345//Get the SIB byte. We don't do anything with it at this point, other 346//than storing it in the ExtMachInst. Determine if we need to get a 347//displacement or immediate next. |
300Decoder::State Decoder::doSIBState(uint8_t nextByte) | 348Decoder::State 349Decoder::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) { --- 4 unchanged lines hidden (view full) --- 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. | 350{ 351 State nextState = ErrorState; 352 emi.sib = nextByte; 353 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 354 consumeByte(); 355 if (emi.modRM.mod == 0 && emi.sib.base == 5) 356 displacementSize = 4; 357 if (displacementSize) { --- 4 unchanged lines hidden (view full) --- 362 instDone = true; 363 nextState = ResetState; 364 } 365 return nextState; 366} 367 368//Gather up the displacement, or at least as much of it 369//as we can get. |
321Decoder::State Decoder::doDisplacementState() | 370Decoder::State 371Decoder::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", --- 30 unchanged lines hidden (view full) --- 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 | 372{ 373 State nextState = ErrorState; 374 375 getImmediate(immediateCollected, 376 emi.displacement, 377 displacementSize); 378 379 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", --- 30 unchanged lines hidden (view full) --- 410 } 411 else 412 nextState = DisplacementState; 413 return nextState; 414} 415 416//Gather up the immediate, or at least as much of it 417//as we can get |
368Decoder::State Decoder::doImmediateState() | 418Decoder::State 419Decoder::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", --- 26 unchanged lines hidden (view full) --- 403 instDone = true; 404 nextState = ResetState; 405 } 406 else 407 nextState = ImmediateState; 408 return nextState; 409} 410 | 420{ 421 State nextState = ErrorState; 422 423 getImmediate(immediateCollected, 424 emi.immediate, 425 immediateSize); 426 427 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", --- 26 unchanged lines hidden (view full) --- 454 instDone = true; 455 nextState = ResetState; 456 } 457 else 458 nextState = ImmediateState; 459 return nextState; 460} 461 |
411DecodeCache::InstMap Decoder::instMap; 412DecodeCache::AddrMap<StaticInstPtr> Decoder::decodePages; | 462Decoder::InstBytes Decoder::dummy; 463Decoder::InstCacheMap Decoder::instCacheMap; |
413 414StaticInstPtr 415Decoder::decode(ExtMachInst mach_inst, Addr addr) 416{ | 464 465StaticInstPtr 466Decoder::decode(ExtMachInst mach_inst, Addr addr) 467{ |
417 StaticInstPtr &si = decodePages.lookup(addr); 418 if (si && (si->machInst == mach_inst)) 419 return si; | 468 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst); 469 if (iter != instMap->end()) 470 return iter->second; |
420 | 471 |
421 DecodeCache::InstMap::iterator iter = instMap.find(mach_inst); 422 if (iter != instMap.end()) { 423 si = iter->second; | 472 StaticInstPtr si = decodeInst(mach_inst); 473 (*instMap)[mach_inst] = si; 474 return si; 475} 476 477StaticInstPtr 478Decoder::decode(PCState &nextPC) 479{ 480 if (!instDone) 481 return NULL; 482 instDone = false; 483 updateNPC(nextPC); 484 485 StaticInstPtr &si = instBytes->si; 486 if (si) |
424 return si; | 487 return si; |
488 489 // We didn't match in the AddrMap, but we still populated an entry. Fix 490 // up its byte masks. 491 const int chunkSize = sizeof(MachInst); 492 493 instBytes->lastOffset = offset; 494 495 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize; 496 Addr firstOffset = origPC - firstBasePC; 497 Addr totalSize = instBytes->lastOffset - firstOffset + 498 (instBytes->chunks.size() - 1) * chunkSize; 499 int start = firstOffset; 500 instBytes->masks.clear(); 501 502 while (totalSize) { 503 int end = start + totalSize; 504 end = (chunkSize < end) ? chunkSize : end; 505 int size = end - start; 506 int idx = instBytes->masks.size(); 507 508 MachInst maskVal = mask(size * 8) << (start * 8); 509 assert(maskVal); 510 511 instBytes->masks.push_back(maskVal); 512 instBytes->chunks[idx] &= instBytes->masks[idx]; 513 totalSize -= size; 514 start = 0; |
|
425 } 426 | 515 } 516 |
427 si = decodeInst(mach_inst); 428 instMap[mach_inst] = si; | 517 si = decode(emi, origPC); |
429 return si; 430} 431 432} | 518 return si; 519} 520 521} |