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] = 0x3FF0FFFFFE;
        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.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->size1 = tmpins->size2 = 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;

                                                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;
                                                }
                                        }
                                }
                                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 = ZStrNew(tmpit->name);
                HashAdd(tmpc, cmp.asm_hash);
                cmp.internal_types[tmpc->raw_type] = tmpc;
        }
        sys_task->hash_table->next = cmp.asm_hash;
}