Deleted Added
sdiff udiff text old ( 9024:5851586f399c ) new ( 9376:270c9a75e91f )
full compact
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;

--- 24 unchanged lines hidden (view full) ---

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);

--- 10 unchanged lines hidden (view full) ---

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();

--- 40 unchanged lines hidden (view full) ---

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 {

--- 13 unchanged lines hidden (view full) ---

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];

--- 11 unchanged lines hidden (view full) ---

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 {

--- 32 unchanged lines hidden (view full) ---

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) {

--- 4 unchanged lines hidden (view full) ---

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",

--- 30 unchanged lines hidden (view full) ---

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",

--- 26 unchanged lines hidden (view full) ---

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}