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; --- 82 unchanged lines hidden (view full) --- 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 case Vex2Of2State: 100 state = doVex2Of2State(nextByte); |
101 break; |
102 case Vex2Of3State: 103 state = doVex2Of3State(nextByte); |
104 break; |
105 case Vex3Of3State: 106 state = doVex3Of3State(nextByte); |
107 break; |
108 case VexOpcodeState: 109 state = doVexOpcodeState(nextByte); 110 break; |
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); --- 97 unchanged lines hidden (view full) --- 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 case Vex2Prefix: 225 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte); |
226 emi.vex.present = 1; 227 nextState = Vex2Of2State; |
228 break; |
229 case Vex3Prefix: 230 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte); |
231 emi.vex.present = 1; 232 nextState = Vex2Of3State; |
233 break; |
234 case 0: 235 nextState = OneByteOpcodeState; 236 break; 237 238 default: 239 panic("Unrecognized prefix %#x\n", nextByte); 240 } 241 return nextState; 242} 243 244Decoder::State |
245Decoder::doVex2Of2State(uint8_t nextByte) |
246{ |
247 consumeByte(); |
248 Vex2Of2 vex = nextByte; |
249 |
250 emi.rex.r = !vex.r; |
251 |
252 emi.vex.l = vex.l; 253 emi.vex.v = ~vex.v; |
254 |
255 switch (vex.p) { 256 case 0: 257 break; 258 case 1: 259 emi.legacy.op = 1; 260 break; 261 case 2: 262 emi.legacy.rep = 1; 263 break; 264 case 3: 265 emi.legacy.repne = 1; 266 break; 267 } 268 269 emi.opcode.type = TwoByteOpcode; 270 271 return VexOpcodeState; |
272} 273 274Decoder::State |
275Decoder::doVex2Of3State(uint8_t nextByte) |
276{ |
277 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) { 278 // This was actually an LDS instruction. Reroute to that path. 279 emi.vex.present = 0; 280 emi.opcode.type = OneByteOpcode; 281 emi.opcode.op = 0xC4; 282 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 283 nextByte >= 0xA0 && nextByte <= 0xA3); 284 } 285 |
286 consumeByte(); |
287 Vex2Of3 vex = nextByte; 288 289 emi.rex.r = !vex.r; 290 emi.rex.x = !vex.x; 291 emi.rex.b = !vex.b; 292 293 switch (vex.m) { 294 case 1: 295 emi.opcode.type = TwoByteOpcode; 296 break; 297 case 2: 298 emi.opcode.type = ThreeByte0F38Opcode; 299 break; 300 case 3: 301 emi.opcode.type = ThreeByte0F3AOpcode; 302 break; 303 default: 304 // These encodings are reserved. Pretend this was an undefined 305 // instruction so the main decoder will behave correctly, and stop 306 // trying to interpret bytes. 307 emi.opcode.type = TwoByteOpcode; 308 emi.opcode.op = 0x0B; 309 instDone = true; 310 return ResetState; 311 } 312 return Vex3Of3State; |
313} 314 315Decoder::State |
316Decoder::doVex3Of3State(uint8_t nextByte) |
317{ |
318 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) { 319 // This was actually an LES instruction. Reroute to that path. 320 emi.vex.present = 0; 321 emi.opcode.type = OneByteOpcode; 322 emi.opcode.op = 0xC5; 323 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 324 nextByte >= 0xA0 && nextByte <= 0xA3); 325 } 326 |
327 consumeByte(); |
328 Vex3Of3 vex = nextByte; 329 330 emi.rex.w = vex.w; 331 332 emi.vex.l = vex.l; 333 emi.vex.v = ~vex.v; 334 335 switch (vex.p) { 336 case 0: 337 break; 338 case 1: 339 emi.legacy.op = 1; 340 break; 341 case 2: 342 emi.legacy.rep = 1; 343 break; 344 case 3: 345 emi.legacy.repne = 1; 346 break; 347 } 348 349 return VexOpcodeState; |
350} 351 |
352Decoder::State 353Decoder::doVexOpcodeState(uint8_t nextByte) 354{ 355 DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte); 356 357 emi.opcode.op = nextByte; 358 359 switch (emi.opcode.type) { 360 case TwoByteOpcode: 361 return processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte); 362 case ThreeByte0F38Opcode: 363 return processOpcode(ImmediateTypeThreeByte0F38, 364 UsesModRMThreeByte0F38); 365 case ThreeByte0F3AOpcode: 366 return processOpcode(ImmediateTypeThreeByte0F3A, 367 UsesModRMThreeByte0F3A); 368 default: 369 panic("Unrecognized opcode type %d.\n", emi.opcode.type); 370 } 371} 372 |
373// Load the first opcode byte. Determine if there are more opcode bytes, and 374// if not, what immediate and/or ModRM is needed. 375Decoder::State 376Decoder::doOneByteOpcodeState(uint8_t nextByte) 377{ 378 State nextState = ErrorState; 379 consumeByte(); 380 |
381 if (nextByte == 0x0f) { |
382 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte); |
383 nextState = TwoByteOpcodeState; |
384 } else { 385 DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte); 386 emi.opcode.type = OneByteOpcode; 387 emi.opcode.op = nextByte; 388 389 nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte, 390 nextByte >= 0xA0 && nextByte <= 0xA3); 391 } --- 105 unchanged lines hidden (view full) --- 497 } else { 498 instDone = true; 499 nextState = ResetState; 500 } 501 } 502 return nextState; 503} 504 |
505//Get the ModRM byte and determine what displacement, if any, there is. 506//Also determine whether or not to get the SIB byte, displacement, or 507//immediate next. 508Decoder::State 509Decoder::doModRMState(uint8_t nextByte) 510{ 511 State nextState = ErrorState; 512 ModRM modRM = nextByte; --- 224 unchanged lines hidden --- |