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; }