decoder.cc revision 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;
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
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          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);
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      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    }
392    return nextState;
393}
394
395// Load the second opcode byte. Determine if there are more opcode bytes, and
396// if not, what immediate and/or ModRM is needed.
397Decoder::State
398Decoder::doTwoByteOpcodeState(uint8_t nextByte)
399{
400    State nextState = ErrorState;
401    consumeByte();
402    if (nextByte == 0x38) {
403        nextState = ThreeByte0F38OpcodeState;
404        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
405    } else if (nextByte == 0x3a) {
406        nextState = ThreeByte0F3AOpcodeState;
407        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
408    } else {
409        DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte);
410        emi.opcode.type = TwoByteOpcode;
411        emi.opcode.op = nextByte;
412
413        nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
414    }
415    return nextState;
416}
417
418// Load the third opcode byte and determine what immediate and/or ModRM is
419// needed.
420Decoder::State
421Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte)
422{
423    consumeByte();
424
425    DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte);
426    emi.opcode.type = ThreeByte0F38Opcode;
427    emi.opcode.op = nextByte;
428
429    return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38);
430}
431
432// Load the third opcode byte and determine what immediate and/or ModRM is
433// needed.
434Decoder::State
435Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte)
436{
437    consumeByte();
438
439    DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte);
440    emi.opcode.type = ThreeByte0F3AOpcode;
441    emi.opcode.op = nextByte;
442
443    return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A);
444}
445
446// Generic opcode processing which determines the immediate size, and whether
447// or not there's a modrm byte.
448Decoder::State
449Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
450                       bool addrSizedImm)
451{
452    State nextState = ErrorState;
453    const uint8_t opcode = emi.opcode.op;
454
455    //Figure out the effective operand size. This can be overriden to
456    //a fixed value at the decoder level.
457    int logOpSize;
458    if (emi.rex.w)
459        logOpSize = 3; // 64 bit operand size
460    else if (emi.legacy.op)
461        logOpSize = altOp;
462    else
463        logOpSize = defOp;
464
465    //Set the actual op size
466    emi.opSize = 1 << logOpSize;
467
468    //Figure out the effective address size. This can be overriden to
469    //a fixed value at the decoder level.
470    int logAddrSize;
471    if (emi.legacy.addr)
472        logAddrSize = altAddr;
473    else
474        logAddrSize = defAddr;
475
476    //Set the actual address size
477    emi.addrSize = 1 << logAddrSize;
478
479    //Figure out the effective stack width. This can be overriden to
480    //a fixed value at the decoder level.
481    emi.stackSize = 1 << stack;
482
483    //Figure out how big of an immediate we'll retreive based
484    //on the opcode.
485    int immType = immTable[opcode];
486    if (addrSizedImm)
487        immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
488    else
489        immediateSize = SizeTypeToSize[logOpSize - 1][immType];
490
491    //Determine what to expect next
492    if (modrmTable[opcode]) {
493        nextState = ModRMState;
494    } else {
495        if (immediateSize) {
496            nextState = ImmediateState;
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;
513    DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
514    if (defOp == 1) {
515        //figure out 16 bit displacement size
516        if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
517            displacementSize = 2;
518        else if (modRM.mod == 1)
519            displacementSize = 1;
520        else
521            displacementSize = 0;
522    } else {
523        //figure out 32/64 bit displacement size
524        if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
525            displacementSize = 4;
526        else if (modRM.mod == 1)
527            displacementSize = 1;
528        else
529            displacementSize = 0;
530    }
531
532    // The "test" instruction in group 3 needs an immediate, even though
533    // the other instructions with the same actual opcode don't.
534    if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
535       if (emi.opcode.op == 0xF6)
536           immediateSize = 1;
537       else if (emi.opcode.op == 0xF7)
538           immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
539    }
540
541    //If there's an SIB, get that next.
542    //There is no SIB in 16 bit mode.
543    if (modRM.rm == 4 && modRM.mod != 3) {
544            // && in 32/64 bit mode)
545        nextState = SIBState;
546    } else if (displacementSize) {
547        nextState = DisplacementState;
548    } else if (immediateSize) {
549        nextState = ImmediateState;
550    } else {
551        instDone = true;
552        nextState = ResetState;
553    }
554    //The ModRM byte is consumed no matter what
555    consumeByte();
556    emi.modRM = modRM;
557    return nextState;
558}
559
560//Get the SIB byte. We don't do anything with it at this point, other
561//than storing it in the ExtMachInst. Determine if we need to get a
562//displacement or immediate next.
563Decoder::State
564Decoder::doSIBState(uint8_t nextByte)
565{
566    State nextState = ErrorState;
567    emi.sib = nextByte;
568    DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte);
569    consumeByte();
570    if (emi.modRM.mod == 0 && emi.sib.base == 5)
571        displacementSize = 4;
572    if (displacementSize) {
573        nextState = DisplacementState;
574    } else if (immediateSize) {
575        nextState = ImmediateState;
576    } else {
577        instDone = true;
578        nextState = ResetState;
579    }
580    return nextState;
581}
582
583//Gather up the displacement, or at least as much of it
584//as we can get.
585Decoder::State
586Decoder::doDisplacementState()
587{
588    State nextState = ErrorState;
589
590    getImmediate(immediateCollected,
591            emi.displacement,
592            displacementSize);
593
594    DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n",
595            displacementSize, immediateCollected);
596
597    if (displacementSize == immediateCollected) {
598        //Reset this for other immediates.
599        immediateCollected = 0;
600        //Sign extend the displacement
601        switch(displacementSize)
602        {
603          case 1:
604            emi.displacement = sext<8>(emi.displacement);
605            break;
606          case 2:
607            emi.displacement = sext<16>(emi.displacement);
608            break;
609          case 4:
610            emi.displacement = sext<32>(emi.displacement);
611            break;
612          default:
613            panic("Undefined displacement size!\n");
614        }
615        DPRINTF(Decoder, "Collected displacement %#x.\n",
616                emi.displacement);
617        if (immediateSize) {
618            nextState = ImmediateState;
619        } else {
620            instDone = true;
621            nextState = ResetState;
622        }
623
624        emi.dispSize = displacementSize;
625    }
626    else
627        nextState = DisplacementState;
628    return nextState;
629}
630
631//Gather up the immediate, or at least as much of it
632//as we can get
633Decoder::State
634Decoder::doImmediateState()
635{
636    State nextState = ErrorState;
637
638    getImmediate(immediateCollected,
639            emi.immediate,
640            immediateSize);
641
642    DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n",
643            immediateSize, immediateCollected);
644
645    if (immediateSize == immediateCollected)
646    {
647        //Reset this for other immediates.
648        immediateCollected = 0;
649
650        //XXX Warning! The following is an observed pattern and might
651        //not always be true!
652
653        //Instructions which use 64 bit operands but 32 bit immediates
654        //need to have the immediate sign extended to 64 bits.
655        //Instructions which use true 64 bit immediates won't be
656        //affected, and instructions that use true 32 bit immediates
657        //won't notice.
658        switch(immediateSize)
659        {
660          case 4:
661            emi.immediate = sext<32>(emi.immediate);
662            break;
663          case 1:
664            emi.immediate = sext<8>(emi.immediate);
665        }
666
667        DPRINTF(Decoder, "Collected immediate %#x.\n",
668                emi.immediate);
669        instDone = true;
670        nextState = ResetState;
671    }
672    else
673        nextState = ImmediateState;
674    return nextState;
675}
676
677Decoder::InstBytes Decoder::dummy;
678Decoder::InstCacheMap Decoder::instCacheMap;
679
680StaticInstPtr
681Decoder::decode(ExtMachInst mach_inst, Addr addr)
682{
683    DecodeCache::InstMap::iterator iter = instMap->find(mach_inst);
684    if (iter != instMap->end())
685        return iter->second;
686
687    StaticInstPtr si = decodeInst(mach_inst);
688    (*instMap)[mach_inst] = si;
689    return si;
690}
691
692StaticInstPtr
693Decoder::decode(PCState &nextPC)
694{
695    if (!instDone)
696        return NULL;
697    instDone = false;
698    updateNPC(nextPC);
699
700    StaticInstPtr &si = instBytes->si;
701    if (si)
702        return si;
703
704    // We didn't match in the AddrMap, but we still populated an entry. Fix
705    // up its byte masks.
706    const int chunkSize = sizeof(MachInst);
707
708    instBytes->lastOffset = offset;
709
710    Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize;
711    Addr firstOffset = origPC - firstBasePC;
712    Addr totalSize = instBytes->lastOffset - firstOffset +
713        (instBytes->chunks.size() - 1) * chunkSize;
714    int start = firstOffset;
715    instBytes->masks.clear();
716
717    while (totalSize) {
718        int end = start + totalSize;
719        end = (chunkSize < end) ? chunkSize : end;
720        int size = end - start;
721        int idx = instBytes->masks.size();
722
723        MachInst maskVal = mask(size * 8) << (start * 8);
724        assert(maskVal);
725
726        instBytes->masks.push_back(maskVal);
727        instBytes->chunks[idx] &= instBytes->masks[idx];
728        totalSize -= size;
729        start = 0;
730    }
731
732    si = decode(emi, origPC);
733    return si;
734}
735
736}
737