decoder.cc revision 10924:d02e9c239892
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#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}
703