decoder.cc revision 10593
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.opcode.type = BadOpcode;
52    emi.opcode.op = 0;
53
54    immediateCollected = 0;
55    emi.immediate = 0;
56    emi.displacement = 0;
57    emi.dispSize = 0;
58
59    emi.modRM = 0;
60    emi.sib = 0;
61
62    if (instBytes->si) {
63        return FromCacheState;
64    } else {
65        instBytes->chunks.clear();
66        return PrefixState;
67    }
68}
69
70void
71Decoder::process()
72{
73    //This function drives the decoder state machine.
74
75    //Some sanity checks. You shouldn't try to process more bytes if
76    //there aren't any, and you shouldn't overwrite an already
77    //decoder ExtMachInst.
78    assert(!outOfBytes);
79    assert(!instDone);
80
81    if (state == ResetState)
82        state = doResetState();
83    if (state == FromCacheState) {
84        state = doFromCacheState();
85    } else {
86        instBytes->chunks.push_back(fetchChunk);
87    }
88
89    //While there's still something to do...
90    while (!instDone && !outOfBytes) {
91        uint8_t nextByte = getNextByte();
92        switch (state) {
93          case PrefixState:
94            state = doPrefixState(nextByte);
95            break;
96          case OneByteOpcodeState:
97            state = doOneByteOpcodeState(nextByte);
98            break;
99          case TwoByteOpcodeState:
100            state = doTwoByteOpcodeState(nextByte);
101            break;
102          case ThreeByte0F38OpcodeState:
103            state = doThreeByte0F38OpcodeState(nextByte);
104            break;
105          case ThreeByte0F3AOpcodeState:
106            state = doThreeByte0F3AOpcodeState(nextByte);
107            break;
108          case ModRMState:
109            state = doModRMState(nextByte);
110            break;
111          case SIBState:
112            state = doSIBState(nextByte);
113            break;
114          case DisplacementState:
115            state = doDisplacementState();
116            break;
117          case ImmediateState:
118            state = doImmediateState();
119            break;
120          case ErrorState:
121            panic("Went to the error state in the decoder.\n");
122          default:
123            panic("Unrecognized state! %d\n", state);
124        }
125    }
126}
127
128Decoder::State
129Decoder::doFromCacheState()
130{
131    DPRINTF(Decoder, "Looking at cache state.\n");
132    if ((fetchChunk & instBytes->masks[chunkIdx]) !=
133            instBytes->chunks[chunkIdx]) {
134        DPRINTF(Decoder, "Decode cache miss.\n");
135        // The chached chunks didn't match what was fetched. Fall back to the
136        // predecoder.
137        instBytes->chunks[chunkIdx] = fetchChunk;
138        instBytes->chunks.resize(chunkIdx + 1);
139        instBytes->si = NULL;
140        chunkIdx = 0;
141        fetchChunk = instBytes->chunks[0];
142        offset = origPC % sizeof(MachInst);
143        basePC = origPC - offset;
144        return PrefixState;
145    } else if (chunkIdx == instBytes->chunks.size() - 1) {
146        // We matched the cache, so use its value.
147        instDone = true;
148        offset = instBytes->lastOffset;
149        if (offset == sizeof(MachInst))
150            outOfBytes = true;
151        return ResetState;
152    } else {
153        // We matched so far, but need to check more chunks.
154        chunkIdx++;
155        outOfBytes = true;
156        return FromCacheState;
157    }
158}
159
160//Either get a prefix and record it in the ExtMachInst, or send the
161//state machine on to get the opcode(s).
162Decoder::State
163Decoder::doPrefixState(uint8_t nextByte)
164{
165    uint8_t prefix = Prefixes[nextByte];
166    State nextState = PrefixState;
167    // REX prefixes are only recognized in 64 bit mode.
168    if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
169        prefix = 0;
170    if (prefix)
171        consumeByte();
172    switch(prefix)
173    {
174        //Operand size override prefixes
175      case OperandSizeOverride:
176        DPRINTF(Decoder, "Found operand size override prefix.\n");
177        emi.legacy.op = true;
178        break;
179      case AddressSizeOverride:
180        DPRINTF(Decoder, "Found address size override prefix.\n");
181        emi.legacy.addr = true;
182        break;
183        //Segment override prefixes
184      case CSOverride:
185      case DSOverride:
186      case ESOverride:
187      case FSOverride:
188      case GSOverride:
189      case SSOverride:
190        DPRINTF(Decoder, "Found segment override.\n");
191        emi.legacy.seg = prefix;
192        break;
193      case Lock:
194        DPRINTF(Decoder, "Found lock prefix.\n");
195        emi.legacy.lock = true;
196        break;
197      case Rep:
198        DPRINTF(Decoder, "Found rep prefix.\n");
199        emi.legacy.rep = true;
200        break;
201      case Repne:
202        DPRINTF(Decoder, "Found repne prefix.\n");
203        emi.legacy.repne = true;
204        break;
205      case RexPrefix:
206        DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte);
207        emi.rex = nextByte;
208        break;
209      case 0:
210        nextState = OneByteOpcodeState;
211        break;
212      default:
213        panic("Unrecognized prefix %#x\n", nextByte);
214    }
215    return nextState;
216}
217
218// Load the first opcode byte. Determine if there are more opcode bytes, and
219// if not, what immediate and/or ModRM is needed.
220Decoder::State
221Decoder::doOneByteOpcodeState(uint8_t nextByte)
222{
223    State nextState = ErrorState;
224    consumeByte();
225    if (nextByte == 0x0f) {
226        nextState = TwoByteOpcodeState;
227        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
228    } else {
229        DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte);
230        emi.opcode.type = OneByteOpcode;
231        emi.opcode.op = nextByte;
232
233        nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
234                                  nextByte >= 0xA0 && nextByte <= 0xA3);
235    }
236    return nextState;
237}
238
239// Load the second opcode byte. Determine if there are more opcode bytes, and
240// if not, what immediate and/or ModRM is needed.
241Decoder::State
242Decoder::doTwoByteOpcodeState(uint8_t nextByte)
243{
244    State nextState = ErrorState;
245    consumeByte();
246    if (nextByte == 0x38) {
247        nextState = ThreeByte0F38OpcodeState;
248        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
249    } else if (nextByte == 0x3a) {
250        nextState = ThreeByte0F3AOpcodeState;
251        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
252    } else {
253        DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte);
254        emi.opcode.type = TwoByteOpcode;
255        emi.opcode.op = nextByte;
256
257        nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
258    }
259    return nextState;
260}
261
262// Load the third opcode byte and determine what immediate and/or ModRM is
263// needed.
264Decoder::State
265Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte)
266{
267    consumeByte();
268
269    DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte);
270    emi.opcode.type = ThreeByte0F38Opcode;
271    emi.opcode.op = nextByte;
272
273    return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38);
274}
275
276// Load the third opcode byte and determine what immediate and/or ModRM is
277// needed.
278Decoder::State
279Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte)
280{
281    consumeByte();
282
283    DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte);
284    emi.opcode.type = ThreeByte0F3AOpcode;
285    emi.opcode.op = nextByte;
286
287    return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A);
288}
289
290// Generic opcode processing which determines the immediate size, and whether
291// or not there's a modrm byte.
292Decoder::State
293Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
294                       bool addrSizedImm)
295{
296    State nextState = ErrorState;
297    const uint8_t opcode = emi.opcode.op;
298
299    //Figure out the effective operand size. This can be overriden to
300    //a fixed value at the decoder level.
301    int logOpSize;
302    if (emi.rex.w)
303        logOpSize = 3; // 64 bit operand size
304    else if (emi.legacy.op)
305        logOpSize = altOp;
306    else
307        logOpSize = defOp;
308
309    //Set the actual op size
310    emi.opSize = 1 << logOpSize;
311
312    //Figure out the effective address size. This can be overriden to
313    //a fixed value at the decoder level.
314    int logAddrSize;
315    if(emi.legacy.addr)
316        logAddrSize = altAddr;
317    else
318        logAddrSize = defAddr;
319
320    //Set the actual address size
321    emi.addrSize = 1 << logAddrSize;
322
323    //Figure out the effective stack width. This can be overriden to
324    //a fixed value at the decoder level.
325    emi.stackSize = 1 << stack;
326
327    //Figure out how big of an immediate we'll retreive based
328    //on the opcode.
329    int immType = immTable[opcode];
330    if (addrSizedImm)
331        immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
332    else
333        immediateSize = SizeTypeToSize[logOpSize - 1][immType];
334
335    //Determine what to expect next
336    if (modrmTable[opcode]) {
337        nextState = ModRMState;
338    } else {
339        if(immediateSize) {
340            nextState = ImmediateState;
341        } else {
342            instDone = true;
343            nextState = ResetState;
344        }
345    }
346    return nextState;
347}
348
349//Get the ModRM byte and determine what displacement, if any, there is.
350//Also determine whether or not to get the SIB byte, displacement, or
351//immediate next.
352Decoder::State
353Decoder::doModRMState(uint8_t nextByte)
354{
355    State nextState = ErrorState;
356    ModRM modRM;
357    modRM = nextByte;
358    DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
359    if (defOp == 1) {
360        //figure out 16 bit displacement size
361        if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
362            displacementSize = 2;
363        else if (modRM.mod == 1)
364            displacementSize = 1;
365        else
366            displacementSize = 0;
367    } else {
368        //figure out 32/64 bit displacement size
369        if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
370            displacementSize = 4;
371        else if (modRM.mod == 1)
372            displacementSize = 1;
373        else
374            displacementSize = 0;
375    }
376
377    // The "test" instruction in group 3 needs an immediate, even though
378    // the other instructions with the same actual opcode don't.
379    if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
380       if (emi.opcode.op == 0xF6)
381           immediateSize = 1;
382       else if (emi.opcode.op == 0xF7)
383           immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
384    }
385
386    //If there's an SIB, get that next.
387    //There is no SIB in 16 bit mode.
388    if (modRM.rm == 4 && modRM.mod != 3) {
389            // && in 32/64 bit mode)
390        nextState = SIBState;
391    } else if(displacementSize) {
392        nextState = DisplacementState;
393    } else if(immediateSize) {
394        nextState = ImmediateState;
395    } else {
396        instDone = true;
397        nextState = ResetState;
398    }
399    //The ModRM byte is consumed no matter what
400    consumeByte();
401    emi.modRM = modRM;
402    return nextState;
403}
404
405//Get the SIB byte. We don't do anything with it at this point, other
406//than storing it in the ExtMachInst. Determine if we need to get a
407//displacement or immediate next.
408Decoder::State
409Decoder::doSIBState(uint8_t nextByte)
410{
411    State nextState = ErrorState;
412    emi.sib = nextByte;
413    DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte);
414    consumeByte();
415    if (emi.modRM.mod == 0 && emi.sib.base == 5)
416        displacementSize = 4;
417    if (displacementSize) {
418        nextState = DisplacementState;
419    } else if(immediateSize) {
420        nextState = ImmediateState;
421    } else {
422        instDone = true;
423        nextState = ResetState;
424    }
425    return nextState;
426}
427
428//Gather up the displacement, or at least as much of it
429//as we can get.
430Decoder::State
431Decoder::doDisplacementState()
432{
433    State nextState = ErrorState;
434
435    getImmediate(immediateCollected,
436            emi.displacement,
437            displacementSize);
438
439    DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n",
440            displacementSize, immediateCollected);
441
442    if(displacementSize == immediateCollected) {
443        //Reset this for other immediates.
444        immediateCollected = 0;
445        //Sign extend the displacement
446        switch(displacementSize)
447        {
448          case 1:
449            emi.displacement = sext<8>(emi.displacement);
450            break;
451          case 2:
452            emi.displacement = sext<16>(emi.displacement);
453            break;
454          case 4:
455            emi.displacement = sext<32>(emi.displacement);
456            break;
457          default:
458            panic("Undefined displacement size!\n");
459        }
460        DPRINTF(Decoder, "Collected displacement %#x.\n",
461                emi.displacement);
462        if(immediateSize) {
463            nextState = ImmediateState;
464        } else {
465            instDone = true;
466            nextState = ResetState;
467        }
468
469        emi.dispSize = displacementSize;
470    }
471    else
472        nextState = DisplacementState;
473    return nextState;
474}
475
476//Gather up the immediate, or at least as much of it
477//as we can get
478Decoder::State
479Decoder::doImmediateState()
480{
481    State nextState = ErrorState;
482
483    getImmediate(immediateCollected,
484            emi.immediate,
485            immediateSize);
486
487    DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n",
488            immediateSize, immediateCollected);
489
490    if(immediateSize == immediateCollected)
491    {
492        //Reset this for other immediates.
493        immediateCollected = 0;
494
495        //XXX Warning! The following is an observed pattern and might
496        //not always be true!
497
498        //Instructions which use 64 bit operands but 32 bit immediates
499        //need to have the immediate sign extended to 64 bits.
500        //Instructions which use true 64 bit immediates won't be
501        //affected, and instructions that use true 32 bit immediates
502        //won't notice.
503        switch(immediateSize)
504        {
505          case 4:
506            emi.immediate = sext<32>(emi.immediate);
507            break;
508          case 1:
509            emi.immediate = sext<8>(emi.immediate);
510        }
511
512        DPRINTF(Decoder, "Collected immediate %#x.\n",
513                emi.immediate);
514        instDone = true;
515        nextState = ResetState;
516    }
517    else
518        nextState = ImmediateState;
519    return nextState;
520}
521
522Decoder::InstBytes Decoder::dummy;
523Decoder::InstCacheMap Decoder::instCacheMap;
524
525StaticInstPtr
526Decoder::decode(ExtMachInst mach_inst, Addr addr)
527{
528    DecodeCache::InstMap::iterator iter = instMap->find(mach_inst);
529    if (iter != instMap->end())
530        return iter->second;
531
532    StaticInstPtr si = decodeInst(mach_inst);
533    (*instMap)[mach_inst] = si;
534    return si;
535}
536
537StaticInstPtr
538Decoder::decode(PCState &nextPC)
539{
540    if (!instDone)
541        return NULL;
542    instDone = false;
543    updateNPC(nextPC);
544
545    StaticInstPtr &si = instBytes->si;
546    if (si)
547        return si;
548
549    // We didn't match in the AddrMap, but we still populated an entry. Fix
550    // up its byte masks.
551    const int chunkSize = sizeof(MachInst);
552
553    instBytes->lastOffset = offset;
554
555    Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize;
556    Addr firstOffset = origPC - firstBasePC;
557    Addr totalSize = instBytes->lastOffset - firstOffset +
558        (instBytes->chunks.size() - 1) * chunkSize;
559    int start = firstOffset;
560    instBytes->masks.clear();
561
562    while (totalSize) {
563        int end = start + totalSize;
564        end = (chunkSize < end) ? chunkSize : end;
565        int size = end - start;
566        int idx = instBytes->masks.size();
567
568        MachInst maskVal = mask(size * 8) << (start * 8);
569        assert(maskVal);
570
571        instBytes->masks.push_back(maskVal);
572        instBytes->chunks[idx] &= instBytes->masks[idx];
573        totalSize -= size;
574        start = 0;
575    }
576
577    si = decode(emi, origPC);
578    return si;
579}
580
581}
582