35#include "debug/Decode.hh"
36#include "debug/Decoder.hh"
56 emi.opcode.type = BadOpcode;
131 panic(
"Went to the error state in the decoder.\n");
146 const uint8_t prefix =
Prefixes[table_idx][nextByte];
154 emi.legacy.op =
true;
158 emi.legacy.addr =
true;
168 emi.legacy.seg = prefix;
172 emi.legacy.lock =
true;
176 emi.legacy.rep =
true;
180 emi.legacy.repne =
true;
201 panic(
"Unrecognized prefix %#x\n", nextByte);
210 Vex2Of2 vex = nextByte;
227 emi.legacy.repne = 1;
231 emi.opcode.type = TwoByteOpcode;
242 emi.opcode.type = OneByteOpcode;
243 emi.opcode.op = 0xC4;
245 nextByte >= 0xA0 && nextByte <= 0xA3);
249 Vex2Of3 vex = nextByte;
257 emi.opcode.type = TwoByteOpcode;
260 emi.opcode.type = ThreeByte0F38Opcode;
263 emi.opcode.type = ThreeByte0F3AOpcode;
269 emi.opcode.type = TwoByteOpcode;
270 emi.opcode.op = 0x0B;
283 emi.opcode.type = OneByteOpcode;
284 emi.opcode.op = 0xC5;
286 nextByte >= 0xA0 && nextByte <= 0xA3);
290 Vex3Of3 vex = nextByte;
307 emi.legacy.repne = 1;
319 emi.opcode.op = nextByte;
322 switch (
emi.opcode.type) {
325 case ThreeByte0F38Opcode:
328 case ThreeByte0F3AOpcode:
332 panic(
"Unrecognized opcode type %d.\n",
emi.opcode.type);
344 if (nextByte == 0x0f) {
349 emi.opcode.type = OneByteOpcode;
350 emi.opcode.op = nextByte;
353 nextByte >= 0xA0 && nextByte <= 0xA3);
365 if (nextByte == 0x38) {
368 }
else if (nextByte == 0x3a) {
373 emi.opcode.type = TwoByteOpcode;
374 emi.opcode.op = nextByte;
388 DPRINTF(
Decoder,
"Found three byte 0F38 opcode %#x.\n", nextByte);
389 emi.opcode.type = ThreeByte0F38Opcode;
390 emi.opcode.op = nextByte;
402 DPRINTF(
Decoder,
"Found three byte 0F3A opcode %#x.\n", nextByte);
403 emi.opcode.type = ThreeByte0F3AOpcode;
404 emi.opcode.op = nextByte;
423 else if (
emi.legacy.op)
429 emi.opSize = 1 << logOpSize;
440 emi.addrSize = 1 << logAddrSize;
448 int immType = immTable[
opcode];
475 ModRM modRM = nextByte;
477 if (
emi.addrSize == 2) {
479 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
481 else if (modRM.mod == 1)
487 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
489 else if (modRM.mod == 1)
497 if (
emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
498 if (
emi.opcode.op == 0xF6)
500 else if (
emi.opcode.op == 0xF7)
506 if (modRM.rm == 4 && modRM.mod != 3 &&
emi.addrSize != 2) {
532 if (
emi.modRM.mod == 0 &&
emi.sib.base == 5)
555 DPRINTF(
Decoder,
"Collecting %d byte displacement, got %d bytes.\n",
574 panic(
"Undefined displacement size!\n");
638 auto iter =
instMap->find(mach_inst);
643 (*instMap)[mach_inst] =
si;
648 DPRINTF(Decode,
"Decode: Decoded %s instruction: %#x\n",
649 si->getName(), mach_inst);
667 const int chunkSize =
sizeof(
MachInst);
674 (
instBytes.chunks.size() - 1) * chunkSize;
675 int start = firstOffset;
679 int end = start + totalSize;
680 end = (chunkSize < end) ? chunkSize : end;
681 int size = end - start;
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
State doPrefixState(uint8_t)
StaticInstPtr decode(ExtMachInst mach_inst, Addr addr)
Decode a machine instruction.
static const ByteTable ImmediateTypeTwoByte
@ ThreeByte0F3AOpcodeState
@ ThreeByte0F38OpcodeState
StaticInstPtr fetchRomMicroop(MicroPC micropc, StaticInstPtr curMacroop) override
State doThreeByte0F3AOpcodeState(uint8_t)
static const ByteTable UsesModRMTwoByte
void updateNPC(X86ISA::PCState &nextPC)
State doVex3Of3State(uint8_t)
decode_cache::InstMap< ExtMachInst > * instMap
static const ByteTable UsesModRMThreeByte0F3A
State doVexOpcodeState(uint8_t)
State doDisplacementState()
const uint8_t ByteTable[256]
State doVex2Of2State(uint8_t)
static const ByteTable ImmediateTypeThreeByte0F38
State doVex2Of3State(uint8_t)
Decoder(const X86DecoderParams &p)
void getImmediate(int &collected, uint64_t ¤t, int size)
State processOpcode(ByteTable &immTable, ByteTable &modrmTable, bool addrSizedImm=false)
static const ByteTable UsesModRMThreeByte0F38
StaticInstPtr decodeInst(ExtMachInst mach_inst)
State doOneByteOpcodeState(uint8_t)
static const uint8_t SizeTypeToSize[3][10]
static const ByteTable Prefixes[2]
State doTwoByteOpcodeState(uint8_t)
X86ISAInst::MicrocodeRom microcodeRom
static const ByteTable ImmediateTypeThreeByte0F3A
State doThreeByte0F38OpcodeState(uint8_t)
static const ByteTable ImmediateTypeOneByte
State doSIBState(uint8_t)
State doModRMState(uint8_t)
static const ByteTable UsesModRMOneByte
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
#define panic(...)
This implements a cprintf based panic() function.
Bitfield< 24, 21 > opcode
This is exposed globally, independent of the ISA.
Copyright (c) 2024 Arm Limited All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
RefCountingPtr< StaticInst > StaticInstPtr