MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / DecodeModRM_64

Method DecodeModRM_64

FEXCore/Source/Interface/Core/Frontend.cpp:246–331  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

244}
245
246void Decoder::DecodeModRM_64(X86Tables::DecodedOperand* Operand, X86Tables::ModRMDecoded ModRM) {
247 uint8_t Displacement {};
248 // Do we have an offset?
249 if (ModRM.mod == 0b01) {
250 Displacement = 1;
251 } else if (ModRM.mod == 0b10) {
252 Displacement = 4;
253 } else if (ModRM.mod == 0 && ModRM.rm == 0b101) {
254 Displacement = 4;
255 }
256
257 // Calculate SIB
258 bool HasSIB = ((ModRM.mod != 0b11) && (ModRM.rm == 0b100));
259
260 if (HasSIB) {
261 FEXCore::X86Tables::SIBDecoded SIB;
262 if (DecodeInst->DecodedSIB) {
263 SIB.Hex = DecodeInst->SIB;
264 } else {
265 // Haven't yet grabbed SIB, pull it now
266 DecodeInst->SIB = ReadByte();
267 SIB.Hex = DecodeInst->SIB;
268 DecodeInst->DecodedSIB = true;
269 }
270
271 // If the SIB base is 0b101, aka BP or R13 then we have a 32bit displacement
272 if (ModRM.mod == 0b00 && ModRM.rm == 0b100 && SIB.base == 0b101) {
273 Displacement = 4;
274 }
275
276 // SIB
277 Operand->Type = DecodedOperand::OpType::SIB;
278 Operand->Data.SIB.Scale = 1 << SIB.scale;
279
280 // The invalid encoding types are described at Table 1-12. "promoted nsigned is always non-zero"
281 {
282 // If we have a VSIB byte (as opposed to SIB), then the index register is a vector.
283 // DecodeInst->TableInfo may be null in the case of 3DNow! ModRM decoding.
284 const bool IsIndexVector = DecodeInst->TableInfo && (DecodeInst->TableInfo->Flags & InstFlags::FLAGS_VEX_VSIB) != 0;
285 uint8_t InvalidSIBIndex = 0b100; ///< SIB Index where there is no register encoding.
286 if (IsIndexVector) {
287 DecodeInst->Flags |= X86Tables::DecodeFlags::FLAG_VSIB_BYTE;
288 InvalidSIBIndex = ~0; ///< No Invalid SIB Index with Index Vectors.
289 }
290
291 const uint8_t IndexREX = (DecodeInst->Flags & DecodeFlags::FLAG_REX_XGPR_X) != 0 ? 1 : 0;
292 const uint8_t BaseREX = (DecodeInst->Flags & DecodeFlags::FLAG_REX_XGPR_B) != 0 ? 1 : 0;
293
294 Operand->Data.SIB.Index = MapModRMToReg(IndexREX, SIB.index, false, false, IsIndexVector, false, InvalidSIBIndex);
295 Operand->Data.SIB.Base = MapModRMToReg(BaseREX, SIB.base, false, false, false, false, ModRM.mod == 0 ? 0b101 : 16);
296 }
297
298 LOGMAN_THROW_A_FMT(Displacement <= 4, "Number of bytes should be <= 4 for literal src");
299
300 if (Displacement) {
301 uint64_t Literal = ReadData(Displacement);
302 if (Displacement == 1) {
303 Literal = static_cast<int8_t>(Literal);

Callers

nothing calls this directly

Calls 1

MapModRMToRegFunction · 0.85

Tested by

no test coverage detected