gem5  v22.0.0.2
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 #include "params/X86Decoder.hh"
48 
49 namespace gem5
50 {
51 
52 namespace X86ISA
53 {
54 
55 class ISA;
56 class Decoder : public InstDecoder
57 {
58  private:
59  // These are defined and documented in decoder_tables.cc
60  static const uint8_t SizeTypeToSize[3][10];
61  typedef const uint8_t ByteTable[256];
62  static ByteTable Prefixes[2];
63 
68 
73 
75 
76  protected:
77  using MachInst = uint64_t;
78 
79  struct InstBytes
80  {
85 
87  {}
88  };
89 
90  static InstBytes dummy;
91 
92  // The bytes to be predecoded.
95  int chunkIdx;
96  // The pc of the start of fetchChunk.
97  Addr basePC = 0;
98  // The pc the current instruction started at.
99  Addr origPC = 0;
100  // The offset into fetchChunk of current processing.
101  int offset = 0;
102  // The extended machine instruction being generated.
104  // Predecoding state.
105  X86Mode mode = LongMode;
107  uint8_t altOp = 0;
108  uint8_t defOp = 0;
109  uint8_t altAddr = 0;
110  uint8_t defAddr = 0;
111  uint8_t stack = 0;
112 
113  uint8_t cpl = 0;
114 
115  uint8_t
117  {
118  return ((uint8_t *)&fetchChunk)[offset];
119  }
120 
121  void
122  getImmediate(int &collected, uint64_t &current, int size)
123  {
124  // Figure out how many bytes we still need to get for the
125  // immediate.
126  int toGet = size - collected;
127  // Figure out how many bytes are left in our "buffer".
128  int remaining = sizeof(MachInst) - offset;
129  // Get as much as we need, up to the amount available.
130  toGet = toGet > remaining ? remaining : toGet;
131 
132  // Shift the bytes we want to be all the way to the right
133  uint64_t partialImm = fetchChunk >> (offset * 8);
134  // Mask off what we don't want.
135  partialImm &= mask(toGet * 8);
136  // Shift it over to overlay with our displacement.
137  partialImm <<= (immediateCollected * 8);
138  // Put it into our displacement.
139  current |= partialImm;
140  // Update how many bytes we've collected.
141  collected += toGet;
142  consumeBytes(toGet);
143  }
144 
145  void
147  {
148  assert(offset <= sizeof(MachInst));
149  if (offset == sizeof(MachInst)) {
150  DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n",
151  chunkIdx, instBytes->chunks.size());
152  chunkIdx++;
153  if (chunkIdx == instBytes->chunks.size()) {
154  outOfBytes = true;
155  } else {
156  offset = 0;
158  basePC += sizeof(MachInst);
159  }
160  }
161  }
162 
163  void
165  {
166  offset++;
168  }
169 
170  void
171  consumeBytes(int numBytes)
172  {
173  offset += numBytes;
175  }
176 
177  // State machine state.
178  protected:
179  // The size of the displacement value.
181  // The size of the immediate value.
183  // This is how much of any immediate value we've gotten. This is used
184  // for both the actual immediate and the displacement.
186 
187  enum State
188  {
204  // We should never get to this state. Getting here is an error.
206  };
207 
209 
210  // Functions to handle each of the states
213  State doPrefixState(uint8_t);
214  State doVex2Of2State(uint8_t);
215  State doVex2Of3State(uint8_t);
216  State doVex3Of3State(uint8_t);
217  State doVexOpcodeState(uint8_t);
218  State doOneByteOpcodeState(uint8_t);
219  State doTwoByteOpcodeState(uint8_t);
222  State doModRMState(uint8_t);
223  State doSIBState(uint8_t);
226 
227  // Process the actual opcode found earlier, using the supplied tables.
228  State processOpcode(ByteTable &immTable, ByteTable &modrmTable,
229  bool addrSizedImm = false);
230  // Process the opcode found with VEX / XOP prefix.
232 
233  protected:
235 
236  typedef RegVal CacheKey;
237 
240  typedef std::unordered_map<CacheKey, DecodePages *> AddrCacheMap;
242 
244  typedef std::unordered_map<
247 
249 
254 
255  void process();
256 
257  public:
258  Decoder(const X86DecoderParams &p) : InstDecoder(p, &fetchChunk)
259  {
260  emi.reset();
261  emi.mode.cpl = cpl;
262  emi.mode.mode = mode;
263  emi.mode.submode = submode;
264  }
265 
266  void
267  setM5Reg(HandyM5Reg m5Reg)
268  {
269  cpl = m5Reg.cpl;
270  mode = (X86Mode)(uint64_t)m5Reg.mode;
271  submode = (X86SubMode)(uint64_t)m5Reg.submode;
272  emi.mode.cpl = cpl;
273  emi.mode.mode = mode;
274  emi.mode.submode = submode;
275  altOp = m5Reg.altOp;
276  defOp = m5Reg.defOp;
277  altAddr = m5Reg.altAddr;
278  defAddr = m5Reg.defAddr;
279  stack = m5Reg.stack;
280 
281  AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg);
282  if (amIter != addrCacheMap.end()) {
283  decodePages = amIter->second;
284  } else {
285  decodePages = new DecodePages;
286  addrCacheMap[m5Reg] = decodePages;
287  }
288 
289  InstCacheMap::iterator imIter = instCacheMap.find(m5Reg);
290  if (imIter != instCacheMap.end()) {
291  instMap = imIter->second;
292  } else {
294  instCacheMap[m5Reg] = instMap;
295  }
296  }
297 
298  void
299  takeOverFrom(InstDecoder *old) override
300  {
302 
303  Decoder *dec = dynamic_cast<Decoder *>(old);
304  assert(dec);
305 
306  cpl = dec->cpl;
307  mode = dec->mode;
308  submode = dec->submode;
309  emi.mode.cpl = cpl;
310  emi.mode.mode = mode;
311  emi.mode.submode = submode;
312  altOp = dec->altOp;
313  defOp = dec->defOp;
314  altAddr = dec->altAddr;
315  defAddr = dec->defAddr;
316  stack = dec->stack;
317  }
318 
319  void
320  reset() override
321  {
323  state = ResetState;
324  }
325 
326  // Use this to give data to the decoder. This should be used
327  // when there is control flow.
328  void
329  moreBytes(const PCStateBase &pc, Addr fetchPC) override
330  {
331  DPRINTF(Decoder, "Getting more bytes.\n");
332  basePC = fetchPC;
333  offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
335  outOfBytes = false;
336  process();
337  }
338 
339  void
341  {
342  if (!nextPC.size()) {
343  int size = basePC + offset - origPC;
345  "Calculating the instruction size: "
346  "basePC: %#x offset: %#x origPC: %#x size: %d\n",
347  basePC, offset, origPC, size);
348  nextPC.size(size);
349  nextPC.npc(nextPC.pc() + size);
350  }
351  }
352 
353  public:
354  StaticInstPtr decode(PCStateBase &next_pc) override;
355 
357  MicroPC micropc, StaticInstPtr curMacroop) override;
358 };
359 
360 } // namespace X86ISA
361 } // namespace gem5
362 
363 #endif // __ARCH_X86_DECODER_HH__
gem5::X86ISA::Decoder::Vex2Of3State
@ Vex2Of3State
Definition: decoder.hh:193
gem5::X86ISA::mask
mask
Definition: misc.hh:796
gem5::GenericISA::PCStateWithNext::pc
Addr pc() const
Definition: pcstate.hh:263
gem5::X86ISA::pc
Bitfield< 19 > pc
Definition: misc.hh:805
gem5::X86ISA::Decoder::doImmediateState
State doImmediateState()
Definition: decoder.cc:635
gem5::X86ISA::Decoder::ImmediateTypeOneByte
static ByteTable ImmediateTypeOneByte
Definition: decoder.hh:69
gem5::X86ISA::Decoder::setM5Reg
void setM5Reg(HandyM5Reg m5Reg)
Definition: decoder.hh:267
gem5::X86ISA::Decoder::altAddr
uint8_t altAddr
Definition: decoder.hh:109
gem5::RegVal
uint64_t RegVal
Definition: types.hh:173
gem5::X86ISA::Decoder::doSIBState
State doSIBState(uint8_t)
Definition: decoder.cc:567
gem5::X86ISA::Decoder::InstCacheMap
std::unordered_map< CacheKey, decode_cache::InstMap< ExtMachInst > * > InstCacheMap
Definition: decoder.hh:245
gem5::X86ISA::Decoder::VexOpcodeState
@ VexOpcodeState
Definition: decoder.hh:195
gem5::X86ISA::Decoder::microcodeRom
static X86ISAInst::MicrocodeRom microcodeRom
Definition: decoder.hh:74
gem5::X86ISA::Decoder::immediateSize
int immediateSize
Definition: decoder.hh:182
gem5::InstDecoder::takeOverFrom
virtual void takeOverFrom(InstDecoder *old)
Take over the state from an old decoder when switching CPUs.
Definition: decoder.hh:89
gem5::X86ISA::Decoder::consumeByte
void consumeByte()
Definition: decoder.hh:164
gem5::decode_cache::InstMap
std::unordered_map< EMI, StaticInstPtr > InstMap
Hash for decoded instructions.
Definition: decode_cache.hh:47
gem5::X86ISA::Decoder::cpl
uint8_t cpl
Definition: decoder.hh:113
gem5::X86ISA::Decoder::TwoByteOpcodeState
@ TwoByteOpcodeState
Definition: decoder.hh:197
gem5::X86ISA::Decoder::DisplacementState
@ DisplacementState
Definition: decoder.hh:202
gem5::X86ISA::Decoder::doVex3Of3State
State doVex3Of3State(uint8_t)
Definition: decoder.cc:319
gem5::X86ISA::Decoder::UsesModRMThreeByte0F38
static ByteTable UsesModRMThreeByte0F38
Definition: decoder.hh:66
gem5::X86ISA::Decoder::DecodePages
decode_cache::AddrMap< Decoder::InstBytes > DecodePages
Definition: decoder.hh:238
gem5::X86ISA::Decoder::stack
uint8_t stack
Definition: decoder.hh:111
microcode_rom.hh
gem5::X86ISA::Decoder::instMap
decode_cache::InstMap< ExtMachInst > * instMap
Definition: decoder.hh:243
gem5::X86ISA::Decoder::defOp
uint8_t defOp
Definition: decoder.hh:108
gem5::X86ISA::Decoder::emi
ExtMachInst emi
Definition: decoder.hh:103
std::vector< MachInst >
gem5::X86ISA::SixtyFourBitMode
@ SixtyFourBitMode
Definition: types.hh:204
gem5::X86ISA::Decoder::ImmediateTypeTwoByte
static ByteTable ImmediateTypeTwoByte
Definition: decoder.hh:70
gem5::X86ISA::Decoder::decodeInst
StaticInstPtr decodeInst(ExtMachInst mach_inst)
gem5::X86ISA::Decoder::ImmediateTypeThreeByte0F3A
static ByteTable ImmediateTypeThreeByte0F3A
Definition: decoder.hh:72
gem5::X86ISA::Decoder::PrefixState
@ PrefixState
Definition: decoder.hh:191
gem5::X86ISA::ExtMachInst::mode
OperatingModeAndCPL mode
Definition: types.hh:245
gem5::X86ISA::Decoder::State
State
Definition: decoder.hh:187
gem5::X86ISA::Decoder::doModRMState
State doModRMState(uint8_t)
Definition: decoder.cc:513
gem5::X86ISAInst::MicrocodeRom
Definition: microcode_rom.hh:42
gem5::X86ISA::Decoder::offset
int offset
Definition: decoder.hh:101
gem5::X86ISA::Decoder::origPC
Addr origPC
Definition: decoder.hh:99
gem5::X86ISA::Decoder::fetchChunk
MachInst fetchChunk
Definition: decoder.hh:93
gem5::RefCountingPtr< StaticInst >
gem5::letoh
T letoh(T value)
Definition: byteswap.hh:173
gem5::X86ISA::Decoder::ByteTable
const typedef uint8_t ByteTable[256]
Definition: decoder.hh:61
gem5::X86ISA::Decoder::doVexOpcodeState
State doVexOpcodeState(uint8_t)
Definition: decoder.cc:356
gem5::X86ISA::X86SubMode
X86SubMode
Definition: types.hh:202
gem5::X86ISA::Decoder::Decoder
Decoder(const X86DecoderParams &p)
Definition: decoder.hh:258
gem5::X86ISA::ExtMachInst::reset
void reset()
Definition: types.hh:214
gem5::X86ISA::Decoder::getNextByte
uint8_t getNextByte()
Definition: decoder.hh:116
gem5::MicroPC
uint16_t MicroPC
Definition: types.hh:149
gem5::X86ISA::Decoder::instBytes
InstBytes * instBytes
Definition: decoder.hh:94
gem5::X86ISA::Decoder::Vex2Of2State
@ Vex2Of2State
Definition: decoder.hh:192
gem5::X86ISA::Decoder::doFromCacheState
State doFromCacheState()
Definition: decoder.cc:148
gem5::X86ISA::Decoder::UsesModRMOneByte
static ByteTable UsesModRMOneByte
Definition: decoder.hh:64
gem5::X86ISA::Decoder::moreBytes
void moreBytes(const PCStateBase &pc, Addr fetchPC) override
Feed data to the decoder.
Definition: decoder.hh:329
decoder.hh
gem5::X86ISA::Decoder::instCacheMap
static InstCacheMap instCacheMap
Definition: decoder.hh:246
gem5::X86ISA::Decoder::ImmediateState
@ ImmediateState
Definition: decoder.hh:203
bitfield.hh
gem5::X86ISA::Decoder::basePC
Addr basePC
Definition: decoder.hh:97
gem5::GenericISA::PCStateWithNext::npc
Addr npc() const
Definition: pcstate.hh:266
gem5::X86ISA::Decoder::InstBytes::masks
std::vector< MachInst > masks
Definition: decoder.hh:83
gem5::X86ISA::Decoder::processExtendedOpcode
State processExtendedOpcode(ByteTable &immTable)
gem5::X86ISA::Prefixes
Prefixes
Definition: types.hh:58
gem5::InstDecoder
Definition: decoder.hh:42
gem5::X86ISA::Decoder::chunkIdx
int chunkIdx
Definition: decoder.hh:95
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::X86ISA::Decoder::ErrorState
@ ErrorState
Definition: decoder.hh:205
gem5::X86ISA::Decoder::SIBState
@ SIBState
Definition: decoder.hh:201
gem5::X86ISA::Decoder::OneByteOpcodeState
@ OneByteOpcodeState
Definition: decoder.hh:196
gem5::X86ISA::Decoder::decodePages
DecodePages * decodePages
Definition: decoder.hh:239
gem5::X86ISA::Decoder::decode
StaticInstPtr decode(ExtMachInst mach_inst, Addr addr)
Decode a machine instruction.
Definition: decoder.cc:678
gem5::decode_cache::AddrMap
A sparse map from an Addr to a Value, stored in page chunks.
Definition: decode_cache.hh:51
gem5::X86ISA::Decoder::updateOffsetState
void updateOffsetState()
Definition: decoder.hh:146
gem5::X86ISA::Decoder::doVex2Of2State
State doVex2Of2State(uint8_t)
Definition: decoder.cc:248
gem5::InstDecoder::outOfBytes
bool outOfBytes
Definition: decoder.hh:50
gem5::X86ISA::Decoder::altOp
uint8_t altOp
Definition: decoder.hh:107
gem5::X86ISA::Decoder::immediateCollected
int immediateCollected
Definition: decoder.hh:185
gem5::X86ISA::Decoder
Definition: decoder.hh:56
gem5::X86ISA::Decoder::InstBytes::si
StaticInstPtr si
Definition: decoder.hh:81
gem5::X86ISA::Decoder::doResetState
State doResetState()
Definition: decoder.cc:47
static_inst.hh
gem5::X86ISA::Decoder::doDisplacementState
State doDisplacementState()
Definition: decoder.cc:588
gem5::InstDecoder::reset
virtual void reset()
Definition: decoder.hh:63
gem5::X86ISA::PCState::size
uint8_t size() const
Definition: pcstate.hh:87
gem5::X86ISA::Decoder::consumeBytes
void consumeBytes(int numBytes)
Definition: decoder.hh:171
gem5::X86ISA::Decoder::InstBytes::lastOffset
int lastOffset
Definition: decoder.hh:84
gem5::X86ISA::Decoder::dummy
static InstBytes dummy
Definition: decoder.hh:90
gem5::X86ISA::Decoder::Vex3Of3State
@ Vex3Of3State
Definition: decoder.hh:194
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::X86ISA::Decoder::doOneByteOpcodeState
State doOneByteOpcodeState(uint8_t)
Definition: decoder.cc:380
gem5::X86ISA::Decoder::processOpcode
State processOpcode(ByteTable &immTable, ByteTable &modrmTable, bool addrSizedImm=false)
Definition: decoder.cc:453
gem5::X86ISA::Decoder::CacheKey
RegVal CacheKey
Caching for decoded instruction objects.
Definition: decoder.hh:236
gem5::X86ISA::Decoder::submode
X86SubMode submode
Definition: decoder.hh:106
gem5::X86ISA::Decoder::fetchRomMicroop
StaticInstPtr fetchRomMicroop(MicroPC micropc, StaticInstPtr curMacroop) override
Definition: decoder.cc:740
gem5::X86ISA::Decoder::AddrCacheMap
std::unordered_map< CacheKey, DecodePages * > AddrCacheMap
Definition: decoder.hh:240
gem5::X86ISA::Decoder::doThreeByte0F3AOpcodeState
State doThreeByte0F3AOpcodeState(uint8_t)
Definition: decoder.cc:439
gem5::X86ISA::Decoder::reset
void reset() override
Definition: decoder.hh:320
gem5::X86ISA::Decoder::MachInst
uint64_t MachInst
Definition: decoder.hh:77
gem5::X86ISA::ExtMachInst
Definition: types.hh:212
gem5::X86ISA::Decoder::FromCacheState
@ FromCacheState
Definition: decoder.hh:190
gem5::X86ISA::Decoder::doVex2Of3State
State doVex2Of3State(uint8_t)
Definition: decoder.cc:278
types.hh
gem5::X86ISA::Decoder::process
void process()
Definition: decoder.cc:78
gem5::X86ISA::Decoder::updateNPC
void updateNPC(X86ISA::PCState &nextPC)
Definition: decoder.hh:340
gem5::X86ISA::Decoder::takeOverFrom
void takeOverFrom(InstDecoder *old) override
Take over the state from an old decoder when switching CPUs.
Definition: decoder.hh:299
gem5::X86ISA::Decoder::defAddr
uint8_t defAddr
Definition: decoder.hh:110
gem5::X86ISA::PCState
Definition: pcstate.hh:50
decode_cache.hh
gem5::X86ISA::Decoder::addrCacheMap
AddrCacheMap addrCacheMap
Definition: decoder.hh:241
gem5::X86ISA::Decoder::doThreeByte0F38OpcodeState
State doThreeByte0F38OpcodeState(uint8_t)
Definition: decoder.cc:425
logging.hh
gem5::X86ISA::Decoder::SizeTypeToSize
static const uint8_t SizeTypeToSize[3][10]
Definition: decoder.hh:60
gem5::X86ISA::p
Bitfield< 0 > p
Definition: pagetable.hh:151
gem5::X86ISA::Decoder::doTwoByteOpcodeState
State doTwoByteOpcodeState(uint8_t)
Definition: decoder.cc:402
trace.hh
gem5::X86ISA::Decoder::state
State state
Definition: decoder.hh:208
gem5::X86ISA::Decoder::InstBytes::InstBytes
InstBytes()
Definition: decoder.hh:86
gem5::PCStateBase
Definition: pcstate.hh:57
gem5::X86ISA::Decoder::displacementSize
int displacementSize
Definition: decoder.hh:180
gem5::X86ISA::Decoder::ThreeByte0F3AOpcodeState
@ ThreeByte0F3AOpcodeState
Definition: decoder.hh:199
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
misc.hh
gem5::X86ISA::Decoder::InstBytes::chunks
std::vector< MachInst > chunks
Definition: decoder.hh:82
gem5::X86ISA::Decoder::getImmediate
void getImmediate(int &collected, uint64_t &current, int size)
Definition: decoder.hh:122
types.hh
gem5::X86ISA::Decoder::ThreeByte0F38OpcodeState
@ ThreeByte0F38OpcodeState
Definition: decoder.hh:198
gem5::X86ISA::Decoder::InstBytes
Definition: decoder.hh:79
gem5::X86ISA::Decoder::ImmediateTypeThreeByte0F38
static ByteTable ImmediateTypeThreeByte0F38
Definition: decoder.hh:71
gem5::X86ISA::Decoder::UsesModRMTwoByte
static ByteTable UsesModRMTwoByte
Definition: decoder.hh:65
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::X86ISA::Decoder::UsesModRMThreeByte0F3A
static ByteTable UsesModRMThreeByte0F3A
Definition: decoder.hh:67
gem5::X86ISA::Decoder::mode
X86Mode mode
Definition: decoder.hh:105
gem5::X86ISA::Decoder::doPrefixState
State doPrefixState(uint8_t)
Definition: decoder.cc:182
gem5::X86ISA::Decoder::ModRMState
@ ModRMState
Definition: decoder.hh:200
gem5::X86ISA::Decoder::ResetState
@ ResetState
Definition: decoder.hh:189

Generated on Thu Jul 28 2022 13:32:22 for gem5 by doxygen 1.8.17