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