gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
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
49namespace gem5
50{
51
52class BaseISA;
53
54namespace X86ISA
55{
56
57class Decoder : public InstDecoder
58{
59 private:
60 // These are defined and documented in decoder_tables.cc
61 static const uint8_t SizeTypeToSize[3][10];
62 typedef const uint8_t ByteTable[256];
64
69
74
76
77 protected:
78 using MachInst = uint64_t;
79
90
92
93 // The bytes to be predecoded.
97 // The pc of the start of fetchChunk.
99 // The pc the current instruction started at.
101 // The offset into fetchChunk of current processing.
102 int offset = 0;
103 // The extended machine instruction being generated.
105 // Predecoding state.
106 X86Mode mode = LongMode;
108 uint8_t altOp = 0;
109 uint8_t defOp = 0;
110 uint8_t altAddr = 0;
111 uint8_t defAddr = 0;
112 uint8_t stack = 0;
113
114 uint8_t cpl = 0;
115
116 uint8_t
118 {
119 return ((uint8_t *)&fetchChunk)[offset];
120 }
121
122 void
123 getImmediate(int &collected, uint64_t &current, int size)
124 {
125 // Figure out how many bytes we still need to get for the
126 // immediate.
127 int toGet = size - collected;
128 // Figure out how many bytes are left in our "buffer".
129 int remaining = sizeof(MachInst) - offset;
130 // Get as much as we need, up to the amount available.
131 toGet = toGet > remaining ? remaining : toGet;
132
133 // Shift the bytes we want to be all the way to the right
134 uint64_t partialImm = fetchChunk >> (offset * 8);
135 // Mask off what we don't want.
136 partialImm &= mask(toGet * 8);
137 // Shift it over to overlay with our displacement.
138 partialImm <<= (immediateCollected * 8);
139 // Put it into our displacement.
140 current |= partialImm;
141 // Update how many bytes we've collected.
142 collected += toGet;
143 consumeBytes(toGet);
144 }
145
146 void
148 {
149 assert(offset <= sizeof(MachInst));
150 if (offset == sizeof(MachInst)) {
151 DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n",
152 chunkIdx, instBytes->chunks.size());
153 chunkIdx++;
154 if (chunkIdx == instBytes->chunks.size()) {
155 outOfBytes = true;
156 } else {
157 offset = 0;
159 basePC += sizeof(MachInst);
160 }
161 }
162 }
163
164 void
166 {
167 offset++;
169 }
170
171 void
172 consumeBytes(int numBytes)
173 {
174 offset += numBytes;
176 }
177
178 // State machine state.
179 protected:
180 // The size of the displacement value.
182 // The size of the immediate value.
184 // This is how much of any immediate value we've gotten. This is used
185 // for both the actual immediate and the displacement.
187
208
210
211 // Functions to handle each of the states
214 State doPrefixState(uint8_t);
215 State doVex2Of2State(uint8_t);
216 State doVex2Of3State(uint8_t);
217 State doVex3Of3State(uint8_t);
218 State doVexOpcodeState(uint8_t);
223 State doModRMState(uint8_t);
224 State doSIBState(uint8_t);
227
228 // Process the actual opcode found earlier, using the supplied tables.
229 State processOpcode(ByteTable &immTable, ByteTable &modrmTable,
230 bool addrSizedImm = false);
231 // Process the opcode found with VEX / XOP prefix.
233
234 protected:
236
238
241 typedef std::unordered_map<CacheKey, DecodePages *> AddrCacheMap;
243
245 typedef std::unordered_map<
248
250
255
256 void process();
257
258 public:
259 Decoder(const X86DecoderParams &p) : InstDecoder(p, &fetchChunk)
260 {
261 emi.reset();
262 emi.mode.cpl = cpl;
263 emi.mode.mode = mode;
264 emi.mode.submode = submode;
265 }
266
267 void
268 setM5Reg(HandyM5Reg m5Reg)
269 {
270 cpl = m5Reg.cpl;
271 mode = (X86Mode)(uint64_t)m5Reg.mode;
272 submode = (X86SubMode)(uint64_t)m5Reg.submode;
273 emi.mode.cpl = cpl;
274 emi.mode.mode = mode;
275 emi.mode.submode = submode;
276 altOp = m5Reg.altOp;
277 defOp = m5Reg.defOp;
278 altAddr = m5Reg.altAddr;
279 defAddr = m5Reg.defAddr;
280 stack = m5Reg.stack;
281
282 AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg);
283 if (amIter != addrCacheMap.end()) {
284 decodePages = amIter->second;
285 } else {
287 addrCacheMap[m5Reg] = decodePages;
288 }
289
290 InstCacheMap::iterator imIter = instCacheMap.find(m5Reg);
291 if (imIter != instCacheMap.end()) {
292 instMap = imIter->second;
293 } else {
295 instCacheMap[m5Reg] = instMap;
296 }
297 }
298
299 void
301 {
303
304 Decoder *dec = dynamic_cast<Decoder *>(old);
305 assert(dec);
306
307 cpl = dec->cpl;
308 mode = dec->mode;
309 submode = dec->submode;
310 emi.mode.cpl = cpl;
311 emi.mode.mode = mode;
312 emi.mode.submode = submode;
313 altOp = dec->altOp;
314 defOp = dec->defOp;
315 altAddr = dec->altAddr;
316 defAddr = dec->defAddr;
317 stack = dec->stack;
318 }
319
320 void
321 reset() override
322 {
325 }
326
327 // Use this to give data to the decoder. This should be used
328 // when there is control flow.
329 void
330 moreBytes(const PCStateBase &pc, Addr fetchPC) override
331 {
332 DPRINTF(Decoder, "Getting more bytes.\n");
333 basePC = fetchPC;
334 offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
336 outOfBytes = false;
337 process();
338 }
339
340 void
342 {
343 if (!nextPC.size()) {
344 int size = basePC + offset - origPC;
346 "Calculating the instruction size: "
347 "basePC: %#x offset: %#x origPC: %#x size: %d\n",
348 basePC, offset, origPC, size);
349 nextPC.size(size);
350 nextPC.npc(nextPC.pc() + size);
351 }
352 }
353
354 public:
355 StaticInstPtr decode(PCStateBase &next_pc) override;
356
358 MicroPC micropc, StaticInstPtr curMacroop) override;
359};
360
361} // namespace X86ISA
362} // namespace gem5
363
364#endif // __ARCH_X86_DECODER_HH__
#define DPRINTF(x,...)
Definition trace.hh:210
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
virtual void takeOverFrom(InstDecoder *old)
Take over the state from an old decoder when switching CPUs.
Definition decoder.hh:89
virtual void reset()
Definition decoder.hh:63
State doPrefixState(uint8_t)
Definition decoder.cc:182
std::unordered_map< CacheKey, decode_cache::InstMap< ExtMachInst > * > InstCacheMap
Definition decoder.hh:246
StaticInstPtr decode(ExtMachInst mach_inst, Addr addr)
Decode a machine instruction.
Definition decoder.cc:678
static ByteTable ImmediateTypeTwoByte
Definition decoder.hh:71
State processExtendedOpcode(ByteTable &immTable)
void consumeBytes(int numBytes)
Definition decoder.hh:172
DecodePages * decodePages
Definition decoder.hh:240
StaticInstPtr fetchRomMicroop(MicroPC micropc, StaticInstPtr curMacroop) override
Definition decoder.cc:741
InstBytes * instBytes
Definition decoder.hh:95
State doThreeByte0F3AOpcodeState(uint8_t)
Definition decoder.cc:439
static ByteTable UsesModRMTwoByte
Definition decoder.hh:66
AddrCacheMap addrCacheMap
Definition decoder.hh:242
uint8_t getNextByte()
Definition decoder.hh:117
void updateNPC(X86ISA::PCState &nextPC)
Definition decoder.hh:341
State doVex3Of3State(uint8_t)
Definition decoder.cc:319
decode_cache::InstMap< ExtMachInst > * instMap
Definition decoder.hh:244
static InstBytes dummy
Definition decoder.hh:91
static ByteTable UsesModRMThreeByte0F3A
Definition decoder.hh:68
State doVexOpcodeState(uint8_t)
Definition decoder.cc:356
void takeOverFrom(InstDecoder *old) override
Take over the state from an old decoder when switching CPUs.
Definition decoder.hh:300
State doDisplacementState()
Definition decoder.cc:588
decode_cache::AddrMap< Decoder::InstBytes > DecodePages
Definition decoder.hh:239
RegVal CacheKey
Caching for decoded instruction objects.
Definition decoder.hh:237
const uint8_t ByteTable[256]
Definition decoder.hh:62
State doVex2Of2State(uint8_t)
Definition decoder.cc:248
static ByteTable ImmediateTypeThreeByte0F38
Definition decoder.hh:72
State doVex2Of3State(uint8_t)
Definition decoder.cc:278
Decoder(const X86DecoderParams &p)
Definition decoder.hh:259
void getImmediate(int &collected, uint64_t &current, int size)
Definition decoder.hh:123
State processOpcode(ByteTable &immTable, ByteTable &modrmTable, bool addrSizedImm=false)
Definition decoder.cc:453
static ByteTable UsesModRMThreeByte0F38
Definition decoder.hh:67
StaticInstPtr decodeInst(ExtMachInst mach_inst)
static InstCacheMap instCacheMap
Definition decoder.hh:247
State doOneByteOpcodeState(uint8_t)
Definition decoder.cc:380
static const uint8_t SizeTypeToSize[3][10]
Definition decoder.hh:61
State doTwoByteOpcodeState(uint8_t)
Definition decoder.cc:402
static X86ISAInst::MicrocodeRom microcodeRom
Definition decoder.hh:75
void setM5Reg(HandyM5Reg m5Reg)
Definition decoder.hh:268
static ByteTable ImmediateTypeThreeByte0F3A
Definition decoder.hh:73
State doThreeByte0F38OpcodeState(uint8_t)
Definition decoder.cc:425
static ByteTable ImmediateTypeOneByte
Definition decoder.hh:70
State doSIBState(uint8_t)
Definition decoder.cc:567
State doModRMState(uint8_t)
Definition decoder.cc:513
void reset() override
Definition decoder.hh:321
void moreBytes(const PCStateBase &pc, Addr fetchPC) override
Feed data to the decoder.
Definition decoder.hh:330
std::unordered_map< CacheKey, DecodePages * > AddrCacheMap
Definition decoder.hh:241
static ByteTable UsesModRMOneByte
Definition decoder.hh:65
uint8_t size() const
Definition pcstate.hh:87
A sparse map from an Addr to a Value, stored in page chunks.
STL vector class.
Definition stl.hh:37
Bitfield< 19 > pc
Definition misc.hh:840
Bitfield< 3 > addr
Definition types.hh:84
Bitfield< 0 > p
Definition pagetable.hh:151
@ SixtyFourBitMode
Definition types.hh:204
std::unordered_map< EMI, StaticInstPtr > InstMap
Hash for decoded instructions.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T letoh(T value)
Definition byteswap.hh:173
uint64_t RegVal
Definition types.hh:173
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint16_t MicroPC
Definition types.hh:149
std::vector< MachInst > chunks
Definition decoder.hh:83
std::vector< MachInst > masks
Definition decoder.hh:84
OperatingModeAndCPL mode
Definition types.hh:245

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0