gem5  v20.1.0.0
decoder.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 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 
29 #ifndef __ARCH_X86_DECODER_HH__
30 #define __ARCH_X86_DECODER_HH__
31 
32 #include <cassert>
33 #include <unordered_map>
34 #include <vector>
35 
36 #include "arch/generic/decoder.hh"
38 #include "arch/x86/regs/misc.hh"
39 #include "arch/x86/types.hh"
40 #include "base/bitfield.hh"
41 #include "base/logging.hh"
42 #include "base/trace.hh"
43 #include "base/types.hh"
44 #include "cpu/decode_cache.hh"
45 #include "cpu/static_inst.hh"
46 #include "debug/Decoder.hh"
47 
48 namespace X86ISA
49 {
50 
51 class ISA;
52 class Decoder : public InstDecoder
53 {
54  private:
55  // These are defined and documented in decoder_tables.cc
56  static const uint8_t SizeTypeToSize[3][10];
57  typedef const uint8_t ByteTable[256];
59 
64 
70 
72 
73  protected:
74  struct InstBytes
75  {
80 
82  {}
83  };
84 
85  static InstBytes dummy;
86 
87  // The bytes to be predecoded.
90  int chunkIdx;
91  // The pc of the start of fetchChunk.
92  Addr basePC = 0;
93  // The pc the current instruction started at.
94  Addr origPC = 0;
95  // The offset into fetchChunk of current processing.
96  int offset = 0;
97  // The extended machine instruction being generated.
99  // Predecoding state.
100  X86Mode mode = LongMode;
102  uint8_t altOp = 0;
103  uint8_t defOp = 0;
104  uint8_t altAddr = 0;
105  uint8_t defAddr = 0;
106  uint8_t stack = 0;
107 
108  uint8_t
110  {
111  return ((uint8_t *)&fetchChunk)[offset];
112  }
113 
114  void
115  getImmediate(int &collected, uint64_t &current, int size)
116  {
117  // Figure out how many bytes we still need to get for the
118  // immediate.
119  int toGet = size - collected;
120  // Figure out how many bytes are left in our "buffer".
121  int remaining = sizeof(MachInst) - offset;
122  // Get as much as we need, up to the amount available.
123  toGet = toGet > remaining ? remaining : toGet;
124 
125  // Shift the bytes we want to be all the way to the right
126  uint64_t partialImm = fetchChunk >> (offset * 8);
127  // Mask off what we don't want.
128  partialImm &= mask(toGet * 8);
129  // Shift it over to overlay with our displacement.
130  partialImm <<= (immediateCollected * 8);
131  // Put it into our displacement.
132  current |= partialImm;
133  // Update how many bytes we've collected.
134  collected += toGet;
135  consumeBytes(toGet);
136  }
137 
138  void
140  {
141  assert(offset <= sizeof(MachInst));
142  if (offset == sizeof(MachInst)) {
143  DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n",
144  chunkIdx, instBytes->chunks.size());
145  chunkIdx++;
146  if (chunkIdx == instBytes->chunks.size()) {
147  outOfBytes = true;
148  } else {
149  offset = 0;
151  basePC += sizeof(MachInst);
152  }
153  }
154  }
155 
156  void
158  {
159  offset++;
161  }
162 
163  void
164  consumeBytes(int numBytes)
165  {
166  offset += numBytes;
168  }
169 
170  // State machine state.
171  protected:
172  // Whether or not we're out of bytes.
173  bool outOfBytes = true;
174  // Whether we've completed generating an ExtMachInst.
175  bool instDone = false;
176  // The size of the displacement value.
178  // The size of the immediate value.
180  // This is how much of any immediate value we've gotten. This is used
181  // for both the actual immediate and the displacement.
183 
184  enum State {
200  // We should never get to this state. Getting here is an error.
202  };
203 
205 
206  // Functions to handle each of the states
209  State doPrefixState(uint8_t);
210  State doVex2Of2State(uint8_t);
211  State doVex2Of3State(uint8_t);
212  State doVex3Of3State(uint8_t);
213  State doVexOpcodeState(uint8_t);
214  State doOneByteOpcodeState(uint8_t);
215  State doTwoByteOpcodeState(uint8_t);
218  State doModRMState(uint8_t);
219  State doSIBState(uint8_t);
222 
223  // Process the actual opcode found earlier, using the supplied tables.
224  State processOpcode(ByteTable &immTable, ByteTable &modrmTable,
225  bool addrSizedImm = false);
226  // Process the opcode found with VEX / XOP prefix.
228 
229  protected:
231 
232  typedef RegVal CacheKey;
233 
236  typedef std::unordered_map<CacheKey, DecodePages *> AddrCacheMap;
238 
240  typedef std::unordered_map<
243 
244  public:
245  Decoder(ISA *isa=nullptr)
246  {
247  emi.reset();
248  emi.mode.mode = mode;
249  emi.mode.submode = submode;
250  }
251 
252  void
253  setM5Reg(HandyM5Reg m5Reg)
254  {
255  mode = (X86Mode)(uint64_t)m5Reg.mode;
256  submode = (X86SubMode)(uint64_t)m5Reg.submode;
257  emi.mode.mode = mode;
258  emi.mode.submode = submode;
259  altOp = m5Reg.altOp;
260  defOp = m5Reg.defOp;
261  altAddr = m5Reg.altAddr;
262  defAddr = m5Reg.defAddr;
263  stack = m5Reg.stack;
264 
265  AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg);
266  if (amIter != addrCacheMap.end()) {
267  decodePages = amIter->second;
268  } else {
269  decodePages = new DecodePages;
270  addrCacheMap[m5Reg] = decodePages;
271  }
272 
273  InstCacheMap::iterator imIter = instCacheMap.find(m5Reg);
274  if (imIter != instCacheMap.end()) {
275  instMap = imIter->second;
276  } else {
278  instCacheMap[m5Reg] = instMap;
279  }
280  }
281 
282  void
284  {
285  mode = old->mode;
286  submode = old->submode;
287  emi.mode.mode = mode;
288  emi.mode.submode = submode;
289  altOp = old->altOp;
290  defOp = old->defOp;
291  altAddr = old->altAddr;
292  defAddr = old->defAddr;
293  stack = old->stack;
294  }
295 
296  void reset() { state = ResetState; }
297 
298  void process();
299 
300  // Use this to give data to the decoder. This should be used
301  // when there is control flow.
302  void
303  moreBytes(const PCState &pc, Addr fetchPC, MachInst data)
304  {
305  DPRINTF(Decoder, "Getting more bytes.\n");
306  basePC = fetchPC;
307  offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
308  fetchChunk = letoh(data);
309  outOfBytes = false;
310  process();
311  }
312 
313  bool needMoreBytes() { return outOfBytes; }
314  bool instReady() { return instDone; }
315 
316  void
318  {
319  if (!nextPC.size()) {
320  int size = basePC + offset - origPC;
322  "Calculating the instruction size: "
323  "basePC: %#x offset: %#x origPC: %#x size: %d\n",
324  basePC, offset, origPC, size);
325  nextPC.size(size);
326  nextPC.npc(nextPC.pc() + size);
327  }
328  }
329 
330  public:
332 
338 
340  MicroPC micropc, StaticInstPtr curMacroop) override;
341 };
342 
343 } // namespace X86ISA
344 
345 #endif // __ARCH_X86_DECODER_HH__
X86ISA::Decoder::UsesModRMThreeByte0F38
static ByteTable UsesModRMThreeByte0F38
Definition: decoder.hh:62
X86ISA::PCState::size
uint8_t size() const
Definition: types.hh:312
X86ISA::ExtMachInst::mode
OperatingMode mode
Definition: types.hh:233
X86ISA::Decoder::updateNPC
void updateNPC(X86ISA::PCState &nextPC)
Definition: decoder.hh:317
X86ISA::Decoder::PrefixState
@ PrefixState
Definition: decoder.hh:187
X86ISA::Decoder::InstBytes::chunks
std::vector< MachInst > chunks
Definition: decoder.hh:77
X86ISA::Decoder::SIBState
@ SIBState
Definition: decoder.hh:197
X86ISA::Decoder::SizeTypeToSize
static const uint8_t SizeTypeToSize[3][10]
Definition: decoder.hh:56
data
const char data[]
Definition: circlebuf.test.cc:42
X86ISA::Decoder::outOfBytes
bool outOfBytes
Definition: decoder.hh:173
X86ISA::Decoder::Prefixes
static ByteTable Prefixes
Definition: decoder.hh:58
X86ISA::Decoder::instReady
bool instReady()
Definition: decoder.hh:314
X86ISA::Decoder::defAddr
uint8_t defAddr
Definition: decoder.hh:105
X86ISA::Decoder::getImmediate
void getImmediate(int &collected, uint64_t &current, int size)
Definition: decoder.hh:115
X86ISA::Decoder::ImmediateTypeVex
static ByteTable ImmediateTypeVex[10]
Definition: decoder.hh:69
X86ISA::Decoder::UsesModRMThreeByte0F3A
static ByteTable UsesModRMThreeByte0F3A
Definition: decoder.hh:63
X86ISA::Decoder::ThreeByte0F3AOpcodeState
@ ThreeByte0F3AOpcodeState
Definition: decoder.hh:195
X86ISA::Decoder::doVex2Of3State
State doVex2Of3State(uint8_t)
Definition: decoder.cc:274
X86ISA::Decoder::AddrCacheMap
std::unordered_map< CacheKey, DecodePages * > AddrCacheMap
Definition: decoder.hh:236
X86ISA::ISA
Definition: isa.hh:50
X86ISA::Decoder::doPrefixState
State doPrefixState(uint8_t)
Definition: decoder.cc:178
X86ISA::Decoder::DisplacementState
@ DisplacementState
Definition: decoder.hh:198
X86ISA::Decoder::updateOffsetState
void updateOffsetState()
Definition: decoder.hh:139
X86ISA::Decoder::process
void process()
Definition: decoder.cc:74
microcode_rom.hh
X86ISA::Decoder::decodeInst
StaticInstPtr decodeInst(ExtMachInst mach_inst)
X86ISA::Decoder::basePC
Addr basePC
Definition: decoder.hh:92
X86ISA::Decoder::altOp
uint8_t altOp
Definition: decoder.hh:102
DecodeCache::AddrMap
A sparse map from an Addr to a Value, stored in page chunks.
Definition: decode_cache.hh:46
X86ISA::Decoder::doVex3Of3State
State doVex3Of3State(uint8_t)
Definition: decoder.cc:315
X86ISA::Decoder::doTwoByteOpcodeState
State doTwoByteOpcodeState(uint8_t)
Definition: decoder.cc:398
X86ISA::MachInst
uint64_t MachInst
Definition: types.hh:52
X86ISA::Decoder::submode
X86SubMode submode
Definition: decoder.hh:101
X86ISA::Decoder::needMoreBytes
bool needMoreBytes()
Definition: decoder.hh:313
std::vector< MachInst >
X86ISA::Decoder::immediateSize
int immediateSize
Definition: decoder.hh:179
X86ISA::Decoder::ResetState
@ ResetState
Definition: decoder.hh:185
X86ISA::Decoder::UsesModRMTwoByte
static ByteTable UsesModRMTwoByte
Definition: decoder.hh:61
X86ISA::Decoder::VexOpcodeState
@ VexOpcodeState
Definition: decoder.hh:191
X86ISA::Decoder::Vex2Of3State
@ Vex2Of3State
Definition: decoder.hh:189
X86ISA::Decoder::moreBytes
void moreBytes(const PCState &pc, Addr fetchPC, MachInst data)
Definition: decoder.hh:303
X86ISA::Decoder::doSIBState
State doSIBState(uint8_t)
Definition: decoder.cc:564
X86ISA::Decoder::mode
X86Mode mode
Definition: decoder.hh:100
X86ISA::Decoder::ImmediateTypeThreeByte0F3A
static ByteTable ImmediateTypeThreeByte0F3A
Definition: decoder.hh:68
GenericISA::SimplePCState::npc
Addr npc() const
Definition: types.hh:161
X86ISA::Decoder::InstBytes::lastOffset
int lastOffset
Definition: decoder.hh:79
letoh
T letoh(T value)
Definition: byteswap.hh:141
X86ISA::Decoder::InstBytes::InstBytes
InstBytes()
Definition: decoder.hh:81
decoder.hh
X86ISA::Decoder::reset
void reset()
Definition: decoder.hh:296
X86ISA::Decoder::ByteTable
const typedef uint8_t ByteTable[256]
Definition: decoder.hh:57
X86ISA::Decoder::Vex3Of3State
@ Vex3Of3State
Definition: decoder.hh:190
X86ISA::Decoder::ImmediateTypeTwoByte
static ByteTable ImmediateTypeTwoByte
Definition: decoder.hh:66
X86ISA::Decoder::consumeBytes
void consumeBytes(int numBytes)
Definition: decoder.hh:164
X86ISA::Decoder::stack
uint8_t stack
Definition: decoder.hh:106
bitfield.hh
X86ISA::Decoder::state
State state
Definition: decoder.hh:204
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
DecodeCache::InstMap
std::unordered_map< EMI, StaticInstPtr > InstMap
Hash for decoded instructions.
Definition: decode_cache.hh:42
X86ISA::Decoder::immediateCollected
int immediateCollected
Definition: decoder.hh:182
X86ISA::Decoder::processOpcode
State processOpcode(ByteTable &immTable, ByteTable &modrmTable, bool addrSizedImm=false)
Definition: decoder.cc:449
X86ISA::Decoder::doModRMState
State doModRMState(uint8_t)
Definition: decoder.cc:509
X86ISA::PCState
Definition: types.hh:287
X86ISA::Decoder::defOp
uint8_t defOp
Definition: decoder.hh:103
X86ISA::Decoder::UsesModRMOneByte
static ByteTable UsesModRMOneByte
Definition: decoder.hh:60
X86ISA::Decoder::doVexOpcodeState
State doVexOpcodeState(uint8_t)
Definition: decoder.cc:352
X86ISA::Decoder::getNextByte
uint8_t getNextByte()
Definition: decoder.hh:109
X86ISA::ExtMachInst
Definition: types.hh:198
X86ISA::Decoder::Decoder
Decoder(ISA *isa=nullptr)
Definition: decoder.hh:245
X86ISAInst::MicrocodeRom
Definition: microcode_rom.hh:39
static_inst.hh
X86ISA::Decoder::decodePages
DecodePages * decodePages
Definition: decoder.hh:235
X86ISA::Decoder::fetchRomMicroop
StaticInstPtr fetchRomMicroop(MicroPC micropc, StaticInstPtr curMacroop) override
Definition: decoder.cc:731
X86ISA::Decoder::ModRMState
@ ModRMState
Definition: decoder.hh:196
X86ISA::Decoder::instDone
bool instDone
Definition: decoder.hh:175
X86ISA::Decoder::instBytes
InstBytes * instBytes
Definition: decoder.hh:89
X86ISA::X86SubMode
X86SubMode
Definition: types.hh:189
X86ISA::Decoder::setM5Reg
void setM5Reg(HandyM5Reg m5Reg)
Definition: decoder.hh:253
X86ISA
This is exposed globally, independent of the ISA.
Definition: acpi.hh:55
X86ISA::Decoder::origPC
Addr origPC
Definition: decoder.hh:94
X86ISA::Decoder::instCacheMap
static InstCacheMap instCacheMap
Definition: decoder.hh:242
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
X86ISA::Decoder::TwoByteOpcodeState
@ TwoByteOpcodeState
Definition: decoder.hh:193
X86ISA::Decoder::chunkIdx
int chunkIdx
Definition: decoder.hh:90
X86ISA::Decoder::ErrorState
@ ErrorState
Definition: decoder.hh:201
X86ISA::Decoder::InstBytes
Definition: decoder.hh:74
X86ISA::Decoder::ImmediateTypeOneByte
static ByteTable ImmediateTypeOneByte
Definition: decoder.hh:65
X86ISA::Decoder::doThreeByte0F38OpcodeState
State doThreeByte0F38OpcodeState(uint8_t)
Definition: decoder.cc:421
X86ISA::Decoder::dummy
static InstBytes dummy
Definition: decoder.hh:85
X86ISA::Decoder::ThreeByte0F38OpcodeState
@ ThreeByte0F38OpcodeState
Definition: decoder.hh:194
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:79
X86ISA::Decoder::addrCacheMap
AddrCacheMap addrCacheMap
Definition: decoder.hh:237
X86ISA::Decoder::ImmediateTypeThreeByte0F38
static ByteTable ImmediateTypeThreeByte0F38
Definition: decoder.hh:67
X86ISA::Decoder::doImmediateState
State doImmediateState()
Definition: decoder.cc:632
X86ISA::Decoder::ImmediateState
@ ImmediateState
Definition: decoder.hh:199
X86ISA::Decoder::fetchChunk
MachInst fetchChunk
Definition: decoder.hh:88
X86ISA::Decoder::doResetState
State doResetState()
Definition: decoder.cc:43
types.hh
X86ISA::Decoder::doVex2Of2State
State doVex2Of2State(uint8_t)
Definition: decoder.cc:244
X86ISA::Decoder::DecodePages
DecodeCache::AddrMap< Decoder::InstBytes > DecodePages
Definition: decoder.hh:234
X86ISA::Decoder::decode
StaticInstPtr decode(ExtMachInst mach_inst, Addr addr)
Decode a machine instruction.
Definition: decoder.cc:675
X86ISA::Decoder::InstBytes::masks
std::vector< MachInst > masks
Definition: decoder.hh:78
X86ISA::Decoder::InstCacheMap
std::unordered_map< CacheKey, DecodeCache::InstMap< ExtMachInst > * > InstCacheMap
Definition: decoder.hh:241
X86ISA::Decoder::takeOverFrom
void takeOverFrom(Decoder *old)
Definition: decoder.hh:283
decode_cache.hh
X86ISA::Decoder::InstBytes::si
StaticInstPtr si
Definition: decoder.hh:76
X86ISA::Decoder::instMap
DecodeCache::InstMap< ExtMachInst > * instMap
Definition: decoder.hh:239
logging.hh
X86ISA::Decoder::doOneByteOpcodeState
State doOneByteOpcodeState(uint8_t)
Definition: decoder.cc:376
GenericISA::SimplePCState::pc
Addr pc() const
Definition: types.hh:158
X86ISA::mask
mask
Definition: misc.hh:796
X86ISA::Decoder::FromCacheState
@ FromCacheState
Definition: decoder.hh:186
X86ISA::Decoder::doDisplacementState
State doDisplacementState()
Definition: decoder.cc:585
X86ISA::Decoder::consumeByte
void consumeByte()
Definition: decoder.hh:157
X86ISA::Decoder::doFromCacheState
State doFromCacheState()
Definition: decoder.cc:144
InstDecoder
Definition: decoder.hh:34
RefCountingPtr< StaticInst >
X86ISA::Decoder::offset
int offset
Definition: decoder.hh:96
X86ISA::Decoder::doThreeByte0F3AOpcodeState
State doThreeByte0F3AOpcodeState(uint8_t)
Definition: decoder.cc:435
trace.hh
X86ISA::SixtyFourBitMode
@ SixtyFourBitMode
Definition: types.hh:190
X86ISA::Decoder::microcodeRom
static X86ISAInst::MicrocodeRom microcodeRom
Definition: decoder.hh:71
X86ISA::Decoder::OneByteOpcodeState
@ OneByteOpcodeState
Definition: decoder.hh:192
MicroPC
uint16_t MicroPC
Definition: types.hh:144
X86ISA::Decoder::displacementSize
int displacementSize
Definition: decoder.hh:177
X86ISA::Decoder::altAddr
uint8_t altAddr
Definition: decoder.hh:104
X86ISA::pc
Bitfield< 19 > pc
Definition: misc.hh:805
X86ISA::Decoder::CacheKey
RegVal CacheKey
Caching for decoded instruction objects.
Definition: decoder.hh:232
X86ISA::Decoder::Vex2Of2State
@ Vex2Of2State
Definition: decoder.hh:188
X86ISA::Decoder
Definition: decoder.hh:52
misc.hh
types.hh
X86ISA::Decoder::emi
ExtMachInst emi
Definition: decoder.hh:98
RegVal
uint64_t RegVal
Definition: types.hh:168
X86ISA::Decoder::State
State
Definition: decoder.hh:184
X86ISA::Decoder::processExtendedOpcode
State processExtendedOpcode(ByteTable &immTable)
X86ISA::ExtMachInst::reset
void reset()
Definition: types.hh:200

Generated on Wed Sep 30 2020 14:01:58 for gem5 by doxygen 1.8.17