decoder.cc revision 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"
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
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}
704