public object TryLookup(CodeContext mode, ImmutableLegacyPrefixList legacyPrefixes, Xex xex, byte opcode, out bool hasModRM, out int immediateSizeInBytes) { if (xex.OpcodeMap == OpcodeMap.Default && opcode == 0x90) { // NOP hasModRM = false; immediateSizeInBytes = 0; return found; } else if (xex.OpcodeMap == OpcodeMap.Escape0F && opcode == 0x1F) { // 3+ byte nop form hasModRM = true; immediateSizeInBytes = 0; return found; } else if (xex.OpcodeMap == OpcodeMap.Default && (opcode & 0xF8) == 0xB0) { // MOV x8, imm8 hasModRM = false; immediateSizeInBytes = 1; return found; } else if (xex.OpcodeMap == OpcodeMap.Default && (opcode & 0xF8) == 0xB8) { // Mov r(16|32|64), imm(16|32|64) OperandSize operandSize; if (mode == CodeContext.SixtyFourBit) operandSize = xex.OperandSize64 ? OperandSize.Qword : OperandSize.Dword; else operandSize = mode.GetDefaultOperandSize().OverrideWordDword( legacyPrefixes.HasOperandSizeOverride); hasModRM = false; immediateSizeInBytes = operandSize.InBytes(); return found; } else if (xex.OpcodeMap == OpcodeMap.Escape0F && (xex.SimdPrefix ?? legacyPrefixes.GetSimdPrefix(xex.OpcodeMap)) == SimdPrefix._66 && opcode == 0x58) { hasModRM = true; immediateSizeInBytes = 0; return found; } else { hasModRM = false; immediateSizeInBytes = 0; return null; } }
object IInstructionDecoderLookup.TryLookup( CodeContext mode, ImmutableLegacyPrefixList legacyPrefixes, Xex xex, byte opcode, out bool hasModRM, out int immediateSizeInBytes) { var operandSize = mode.GetEffectiveOperandSize(legacyPrefixes, xex); var addressSize = mode.GetEffectiveAddressSize(legacyPrefixes); InstructionDefinition bestMatch = null; int bestOperandSizeMatchLevel = -1; var lookupKey = OpcodeEnum.MakeLookupKey(legacyPrefixes.GetSimdPrefix(xex.OpcodeMap), xex.OpcodeMap, opcode); foreach (var instruction in byOpcodeKey[lookupKey]) { var encoding = instruction.Encoding; // Ensure we match the RexW requirements if ((encoding & InstructionEncoding.RexW_Mask) == InstructionEncoding.RexW_Fixed && xex.OperandSize64 != ((instruction.Opcode & Opcode.RexW) != 0)) { continue; } // Ensure we match the opcode if ((opcode & encoding.GetOpcodeMainByteFixedMask()) != instruction.Opcode.GetMainByte()) continue; // Record the candidate, favoring more specific operand size matches var operandSizeMatchLevel = GetOperandSizeMatchLevel(encoding, operandSize); if (operandSizeMatchLevel > bestOperandSizeMatchLevel) { bestMatch = instruction; bestOperandSizeMatchLevel = operandSizeMatchLevel; } } if (bestMatch == null) { hasModRM = false; immediateSizeInBytes = 0; return null; } hasModRM = bestMatch.Encoding.HasModRM(); immediateSizeInBytes = bestMatch.Encoding.GetImmediatesSizeInBytes(operandSize, addressSize); return bestMatch; }