| 244 | } |
| 245 | |
| 246 | void 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); |
nothing calls this directly
no test coverage detected