decoder.cc (11321:02e930db812d) decoder.cc (11793:ef606668d247)
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
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}