decoder.cc (11793:ef606668d247) decoder.cc (12045:31d9a81ba286)
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;
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
100 case TwoByteVexState:
101 state = doTwoByteVexState(nextByte);
99 case Vex2Of2State:
100 state = doVex2Of2State(nextByte);
102 break;
101 break;
103
104 case ThreeByteVexFirstState:
105 state = doThreeByteVexFirstState(nextByte);
102 case Vex2Of3State:
103 state = doVex2Of3State(nextByte);
106 break;
104 break;
107
108 case ThreeByteVexSecondState:
109 state = doThreeByteVexSecondState(nextByte);
105 case Vex3Of3State:
106 state = doVex3Of3State(nextByte);
110 break;
107 break;
111
108 case VexOpcodeState:
109 state = doVexOpcodeState(nextByte);
110 break;
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);

--- 97 unchanged lines hidden (view full) ---

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;
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;
225
226 case Vex2Prefix:
227 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte);
224 case Vex2Prefix:
225 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte);
228 emi.vex.zero = nextByte;
229 nextState = TwoByteVexState;
226 emi.vex.present = 1;
227 nextState = Vex2Of2State;
230 break;
228 break;
231
232 case Vex3Prefix:
233 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte);
229 case Vex3Prefix:
230 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte);
234 emi.vex.zero = nextByte;
235 nextState = ThreeByteVexFirstState;
231 emi.vex.present = 1;
232 nextState = Vex2Of3State;
236 break;
233 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
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
249Decoder::doTwoByteVexState(uint8_t nextByte)
245Decoder::doVex2Of2State(uint8_t nextByte)
250{
246{
251 assert(emi.vex.zero == 0xc5);
252 consumeByte();
247 consumeByte();
253 TwoByteVex tbe = 0;
254 tbe.first = nextByte;
248 Vex2Of2 vex = nextByte;
255
249
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;
250 emi.rex.r = !vex.r;
260
251
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;
252 emi.vex.l = vex.l;
253 emi.vex.v = ~vex.v;
265
254
266 emi.opcode.type = Vex;
267 return OneByteOpcodeState;
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;
268}
269
270Decoder::State
272}
273
274Decoder::State
271Decoder::doThreeByteVexFirstState(uint8_t nextByte)
275Decoder::doVex2Of3State(uint8_t nextByte)
272{
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
273 consumeByte();
286 consumeByte();
274 emi.vex.first = nextByte;
275 return ThreeByteVexSecondState;
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;
276}
277
278Decoder::State
313}
314
315Decoder::State
279Decoder::doThreeByteVexSecondState(uint8_t nextByte)
316Decoder::doVex3Of3State(uint8_t nextByte)
280{
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
281 consumeByte();
327 consumeByte();
282 emi.vex.second = nextByte;
283 emi.opcode.type = Vex;
284 return OneByteOpcodeState;
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;
285}
286
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
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
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
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;
381 if (nextByte == 0x0f) {
302 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
382 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
383 nextState = TwoByteOpcodeState;
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 }

--- 105 unchanged lines hidden (view full) ---

416 } else {
417 instDone = true;
418 nextState = ResetState;
419 }
420 }
421 return nextState;
422}
423
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
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;

--- 224 unchanged lines hidden ---
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 ---