U0 AsmParseInsFlags(CCompCtrl *cc, CInst *tmpins)
{
    I64 i;

    while (TRUE)
    {
        switch (cc->token)
        {
            case TK_IDENT:
                if ((i = ListMatch(cc->cur_str, "NO\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0")) >= 0)
                {
                    tmpins->opcode_modifier = i;
                    break;
                }
                else
                    return;

            case TK_I64:
                if (cc->cur_i64 == 16)
                    tmpins->flags |= IEF_OP_SIZE16;
                else if (cc->cur_i64 == 32)
                    tmpins->flags |= IEF_OP_SIZE32;
                else
                    return;
                break;

            case '+':
                tmpins->flags |= IEF_PLUS_OPCODE;
            case '/':
                if (Lex(cc) == TK_I64 && cc->cur_i64 < 8)
                    tmpins->slash_val = cc->cur_i64;
                else if (cc->token == TK_IDENT)
                {
                    if (!StrCompare(cc->cur_str, "R"))
                        tmpins->slash_val = SV_R_REG;
                    else if (!StrCompare(cc->cur_str, "I"))
                        tmpins->slash_val = SV_I_REG;
                    else
                        return;
                }
                else
                    return;
                break;

            case '!': tmpins->flags |= IEF_DONT_SWITCH_MODES;   break;
            case '&': tmpins->flags |= IEF_DEFAULT;             break;
            case '%': tmpins->flags |= IEF_NOT_IN_64_BIT;       break;
            case '=': tmpins->flags |= IEF_48_REX;              break;
            case '`': tmpins->flags |= IEF_REX_ONLY_R8_R15;     break;
            case '^': tmpins->flags |= IEF_REX_XOR_LIKE;        break;
            case '*': tmpins->flags |= IEF_STI_LIKE;            break;
            case '$': tmpins->flags |= IEF_ENDING_ZERO;         break;

            default:
                return;
        }
        Lex(cc);
    }
}

U0 AsmHashLoad()
{//See ::/Compiler/OpCodes.DD.
    I64              i, j, size, size_max;
    CInternalType   *tmpit;
    CCompCtrl       *cc;
    CHashGeneric    *tmph;
    CHashReg        *tmpr;
    CHashOpcode     *tmpo, *tmpo2, *tmpo_max;
    CInst           *tmpins;
    CHashClass      *tmpc;

    cmp.size_arg_mask[0]  = 0xF0003FF0FFFFFE;
    cmp.size_arg_mask[1]  = 0x1110111112;
    cmp.size_arg_mask[2]  = 0x2220222224;
    cmp.size_arg_mask[4]  = 0x0440444448;
    cmp.size_arg_mask[8]  = 0x0880888880;
    cmp.size_arg_mask[16] = 0xF8000000000000; 

    cmp.asm_hash = HashTableNew(1024);
    size_max = offset(CHashOpcode.ins) + sizeof(CInst) << 5;
    tmpo_max = MAlloc(size_max);

    cc = CompCtrlNew(FileRead("OpCodes.DD"),, "OpCodes.DD");
    cc->htc.hash_table_list = NULL;
    Lex(cc);
    while (cc->token)
    {
        if (cc->token != TK_IDENT)
            LexExcept(cc, "Expecting identifier at ");
        i = ListMatch(cc->cur_str, "NONE\0R8\0R16\0R32\0R64\0SEG\0FSTACK\0MM\0XMM\0OPCODE\0KEYWORD\0ASM_KEYWORD\0");
        if (i <= 0)
            LexExcept(cc, "Unknown Statement");
        Lex(cc); //skip keyword
        if (cc->token != TK_IDENT)
            LexExcept(cc, "Expecting identifier at ");
        switch (i)
        {
            case REGT_R8...REGT_XMM:
                tmpr = CAlloc(sizeof(CHashReg));
                tmpr->str = cc->cur_str;
                cc->cur_str = NULL;
                Lex(cc); //skip keyword name
                if (cc->token != TK_I64)
                    LexExcept(cc, "Expecting int at ");
                tmpr->type = HTT_REG;
                tmpr->reg_type = i;
                tmpr->reg_num = cc->cur_i64;
                HashAdd(tmpr, cmp.asm_hash);
                Lex(cc); //Skip INT
                break;

            case: //OPCODE
                if (cc->token != TK_IDENT)
                    LexExcept(cc, "Expecting opcode at ");
                MemSet(tmpo_max, 0, size_max);
                tmpo_max->type = HTT_OPCODE;
                tmpo_max->inst_entry_count = 0;
                tmpo_max->str = cc->cur_str;
                cc->cur_str = 0;
                Lex(cc);                //Skip OPCODE
                while (cc->token && cc->token != ';' && cc->token != ':')
                {
                    tmpins = &tmpo_max->ins[tmpo_max->inst_entry_count];
                    tmpins->ins_entry_num = tmpo_max->inst_entry_count++;
                    tmpins->slash_val = SV_NONE; //Not zero!!
                    while (cc->token == TK_I64) {
                        tmpins->opcode[tmpins->opcode_count++] = cc->cur_i64;
                        Lex(cc);
                    }
                    if (cc->token == ',')
                        Lex(cc);
                    else if (cc->token != ';')
                        LexExcept(cc, "Expecting ',' at ");

                    AsmParseInsFlags(cc, tmpins);

                    tmpins->uasm_slash_val = tmpins->slash_val;
                    if (tmpins->flags & IEF_STI_LIKE && tmpins->slash_val != SV_I_REG)
                        tmpins->uasm_slash_val = SV_STI_LIKE;

                    tmpins->arg1 = tmpins->arg2 = tmpins->arg3 = tmpins->size1 = tmpins->size2 = tmpins->size3 = 0;
                    if (cc->token == TK_IDENT)
                    {
                        j = DefineMatch(cc->cur_str, "ST_ARG_TYPES");
                        tmpins->arg1 = j;
                        if (Bt(&cmp.size_arg_mask[1], j))
                            tmpins->size1 = 8;
                        else if (Bt(&cmp.size_arg_mask[2], j))
                            tmpins->size1 = 16;
                        else if (Bt(&cmp.size_arg_mask[4], j))
                            tmpins->size1 = 32;
                        else if (Bt(&cmp.size_arg_mask[8], j))
                            tmpins->size1 = 64;
                        else if (Bt(&cmp.size_arg_mask[16], j))
                            tmpins->size1 = 128;

                        if (Lex(cc) == TK_IDENT)
                        {
                            j = DefineMatch(cc->cur_str, "ST_ARG_TYPES");
                            Lex(cc);
                            tmpins->arg2 = j;
                            if (Bt(&cmp.size_arg_mask[1],j))
                                tmpins->size2 = 8;
                            else if (Bt(&cmp.size_arg_mask[2], j))
                                tmpins->size2 = 16;
                            else if (Bt(&cmp.size_arg_mask[4], j))
                                tmpins->size2 = 32;
                            else if (Bt(&cmp.size_arg_mask[8], j))
                                tmpins->size2 = 64;
                            else if (Bt(&cmp.size_arg_mask[16], j))
                                tmpins->size2 = 128;

                            if (cc->token == TK_IDENT)
                            {
                                j = DefineMatch(cc->cur_str, "ST_ARG_TYPES");
                                Lex(cc);
                                tmpins->arg3 = j;
                                if (Bt(&cmp.size_arg_mask[1],j))
                                    tmpins->size3 = 8;
                            }
                        }
                    }
                }
                size = offset(CHashOpcode.ins) + sizeof(CInst) * tmpo_max->inst_entry_count;
                tmpo = MAlloc(size);
                MemCopy(tmpo, tmpo_max, size);
                tmpo->use_count = 0;
                if (HashFind(tmpo->str, cmp.asm_hash, HTT_OPCODE))
                    LexExcept(cc, "Duplicate OPCODE entry ");
                HashAdd(tmpo, cmp.asm_hash);
                //Parse aliases.
                if (cc->token == ':')
                {
                    while (Lex(cc) == TK_IDENT)
                    {
                        tmpo2 = MAllocIdent(tmpo);
                        tmpo2->str = cc->cur_str;
                        cc->cur_str = 0;
                        tmpo2->oc_flags |= OCF_ALIAS;
                        if (HashFind(tmpo2->str, cmp.asm_hash, HTT_OPCODE))
                            LexExcept(cc, "Duplicate OPCODE ALIAS entry ");
                        HashAdd(tmpo2, cmp.asm_hash);
                    }
                }
                break;

            case: //KEYWORD
            case: //ASM_KEYWORD
                tmph = CAlloc(sizeof(CHashGeneric));
                tmph->str = cc->cur_str;
                cc->cur_str = NULL;
                Lex(cc); //skip keyword name
                if (cc->token != TK_I64)
                    LexExcept(cc, "Expecting int at ");
                tmph->user_data0 = cc->cur_i64;
                if (i == 10)
                    tmph->type = HTT_KEYWORD;
                else
                    tmph->type = HTT_ASM_KEYWORD;
                HashAdd(tmph, cmp.asm_hash);
                Lex(cc); //Skip INT
                break;
        }
        if (cc->token != ';')
            LexExcept(cc, "Missing ';' at");
        Lex(cc); //Skip ';'
    }
    Free(tmpo_max);
    CompCtrlDel(cc);
    for (i = 0; i < INTERNAL_TYPES_NUM; i++)
    {
        tmpit = &internal_types_table[i];
        tmpc = ParseClassNew;
        tmpc->type = HTT_INTERNAL_TYPE;
        tmpc->raw_type = tmpit->type;
        Bts(&tmpc->flags, Cf_INTERNAL_TYPE);
        tmpc->size = tmpit->size;
        tmpc->str = SysStrNew(tmpit->name);
        HashAdd(tmpc, cmp.asm_hash);
        cmp.internal_types[tmpc->raw_type] = tmpc;
    }
    sys_task->hash_table->next = cmp.asm_hash;
}