void MnemonicTranslateImplicitAlias(char* Mnemonic, Inst* Instruction)
{
    // Avoid naming conflicts (SSE "_XMM", MOVSX*)
    if(strchr(Mnemonic, '_') ||
            strchr(Mnemonic, 'X') ||
            strchr(Mnemonic, 'x'))
        return;

    // Certain string instructions need to override the instruction size
    if(!_strnicmp(Mnemonic, "ins", 3) ||
            !_strnicmp(Mnemonic, "outs", 4) ||
            !_strnicmp(Mnemonic, "movs", 4) ||
            !_strnicmp(Mnemonic, "cmps", 4) ||
            !_strnicmp(Mnemonic, "stos", 4) ||
            !_strnicmp(Mnemonic, "lods", 4) ||
            !_strnicmp(Mnemonic, "scas", 4))
    {
        if(Instruction->OperandCount >= 2)
        {
            // Determine size from the MEMORY operand REGISTER
            auto operands = Instruction->Operands;

            if(operands[0].Type == OPERAND_MEM)
                Instruction->AddressSizeOverride = OpsizeToBits(RegGetSize(operands[0].Mem.BaseVal));
            else if(operands[1].Type == OPERAND_MEM)
                Instruction->AddressSizeOverride = OpsizeToBits(RegGetSize(operands[1].Mem.BaseVal));
        }

        // All operands are implicit/hidden
        Instruction->OperandCount = 0;
    }
}
bool AnalyzeOperand(XEDPARSE* Parse, const char* Value, InstOperand* Operand)
{
    REG registerVal     = RegFromString(Value);
    ULONGLONG immVal    = 0;

    if(registerVal != REG_INVALID)
    {
        // Register
        Operand->Type       = OPERAND_REG;
        Operand->Segment    = REG_INVALID;
        Operand->Size       = RegGetSize(registerVal);
        Operand->XedEOSZ    = OpsizeToEosz(Operand->Size);
        Operand->Reg.Reg    = registerVal;
        Operand->Reg.XedReg = RegToXed(registerVal);
    }
    else if(strchr(Value, '[') && strchr(Value, ']'))
    {
        // Memory
        Operand->Type       = OPERAND_MEM;
        Operand->Segment    = REG_INVALID;
        Operand->Size       = SIZE_UNSET;
        Operand->XedEOSZ    = EOSZ_64_32(Parse->x64);

        return HandleMemoryOperand(Parse, Value, Operand);
    }
    else if(strchr(Value, ':'))
    {
        // Segment selector operand
        Operand->Type       = OPERAND_SEGSEL;
        Operand->Segment    = REG_INVALID;
        Operand->Size       = SIZE_DWORD;
        Operand->XedEOSZ    = EOSZ_64_32(Parse->x64);

        return HandleSegSelectorOperand(Parse, Value, Operand);
    }
    else if(valfromstring(Value, &immVal) || (Parse->cbUnknown && Parse->cbUnknown(Value, &immVal)))
    {
        // Immediate
        Operand->Type       = OPERAND_IMM;
        Operand->Segment    = REG_INVALID;
        Operand->Size       = OpsizeFromValue(immVal);
        Operand->XedEOSZ    = EOSZ_64_32(Parse->x64);
        Operand->Imm.Signed = (Value[0] == '-');
        Operand->Imm.imm    = immVal;
    }
    else
    {
        // Unknown
        Operand->Type = OPERAND_INVALID;

        sprintf(Parse->error, "Unknown operand identifier '%s'", Value);
        return false;
    }

    return true;
}