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