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