void LoadAsmHash(BoolU4 first) { U8 i,j,type; U4 *dd; LexStruct *lx; I8 size,size1; SysHashEntry *temph; OpcodeHashEntry *tempo,*tempo1; InstructionEntry *tempi; ClassStruct *tempc; asm_hash=NewHashTable(2048); size1=offset(OpcodeHashEntry.ins)+sizeof(InstructionEntry)<<5; tempo=MAlloc(size1); lx=LexNew(ReadTextFile("OpCodes.TXZ"),0,NewStr("OpCodes.TXZ")); lx->hash_table_list=NULL; Lex(lx); while (lx->token) { if (lx->token!=TK_IDENT) PutAsmError(lx,"ST_EXPECTING_IDENTIFIER"); else { i=MatchListEntry(lx->ident,"OPCODE\0KEYWORD\0R8\0R16\0R32\0R64\0SEG\0\0",MLE_IGNORE_CASE); Lex(lx); //skip keyword if (!i) { //OPCODE MemSet(tempo,0,size1); tempo->type=HTT_OPCODE; tempo->instruction_entry_cnt=0; tempo->str=lx->ident; lx->ident=0; Lex(lx); //Skip OPCODE while (lx->token && lx->token!=';') { tempi=&tempo->ins[tempo->instruction_entry_cnt]; tempi->ins_entry_num=tempo->instruction_entry_cnt++; tempi->opcode_cnt=0; while (lx->token==TK_INTEGER) { tempi->opcode[tempi->opcode_cnt++]=lx->cur_i; Lex(lx); } tempi->flags=0; if (lx->token=='+') { tempi->flags|=IEF_PLUS_OPCODE; Lex(lx); } if (lx->token=='/') { if (Lex(lx)==TK_INTEGER) { tempi->slash_value=lx->cur_i; Lex(lx); } else if (lx->token==TK_IDENT) { tempi->slash_value=SV_REGISTER; Lex(lx); } } else tempi->slash_value=SV_NONE; if (lx->token=='*') { tempi->flags|=IEF_OP_SIZE16; Lex(lx); } if (lx->token==TK_MOD_EQUAL) { tempi->flags|=IEF_OP_SIZE32|IEF_48_REX; Lex(lx); } if (lx->token=='%') { tempi->flags|=IEF_OP_SIZE32; Lex(lx); } if (lx->token=='!') { tempi->flags|=IEF_DONT_SWITCH_MODES; Lex(lx); } if (lx->token=='&') { tempi->flags|=IEF_DEFAULT; Lex(lx); } if (lx->token=='-') { tempi->flags|=IEF_NO_REX; Lex(lx); } if (lx->token=='~') { tempi->flags|=IEF_40_REX; Lex(lx); } if (lx->token=='~') { tempi->flags|=IEF_40_REX; Lex(lx); } else if (lx->token=='=') { tempi->flags|=IEF_48_REX; Lex(lx); } if (lx->token!=TK_IDENT) PutAsmError(lx,"ST_EXPECTING_IDENTIFIER"); else { tempi->opcode_modifier=MatchSysTextEntry(lx->ident, "ST_OPCODE_MODIFIERS",MLE_IGNORE_CASE); tempi->arg1=0; tempi->arg2=0; if (Lex(lx)==TK_IDENT) { j=MatchSysTextEntry(lx->ident, "ST_ARGUMENT_TYPES",MLE_IGNORE_CASE); tempi->arg1=j; if (j>=ARGT_REL8 && j<=ARGT_REL32 || j>=ARGT_MOFFS8 && j<=ARGT_MOFFS64) tempi|=IEF_NO_REX; if (Lex(lx)==TK_IDENT) { j=MatchSysTextEntry(lx->ident, "ST_ARGUMENT_TYPES",MLE_IGNORE_CASE); Lex(lx); tempi->arg2=j; if (j>=ARGT_REL8 && j<=ARGT_REL32 || j>=ARGT_MOFFS8 && j<=ARGT_MOFFS64) tempi|=IEF_NO_REX; } } } } if (lx->token==';') { Lex(lx); //Skip ';' size=offset(OpcodeHashEntry.ins)+ sizeof(InstructionEntry)*tempo->instruction_entry_cnt; tempo1=MAlloc(size); MemCpy(tempo1,tempo,size); tempo1->use_cnt=0; SetSourceFileInfo(lx,tempo1); AddSysHashEntry(tempo1,asm_hash); } else PutAsmError(lx,"ST_MISSING_SEMICOLON"); } else if (i>=1 && i<=6) { //KEYWORD,R8,R16,R32,R64,SEG if (lx->token!=TK_IDENT) PutAsmError(lx,"ST_EXPECTING_IDENTIFIER"); else { temph=MAllocZ(sizeof(SysHashEntry)); temph->str=lx->ident; lx->ident=NULL; temph->use_cnt=0; SetSourceFileInfo(lx,temph); Lex(lx); //skip keyword name if (lx->token!=TK_INTEGER) PutAsmError(lx,"ST_EXPECTING_INTEGER"); else { temph->user_data0=lx->cur_i; if (Lex(lx)!=';') PutAsmError(lx,"ST_MISSING_SEMICOLON"); else { Lex(lx); //skip ';' AddSysHashEntry(temph,asm_hash); } } switch (i) { case 1: temph->type=HTT_KEYWORD; if (first) { temph=MAllocIdentical(temph); AddSysHashEntry(temph,adam_tss->hash_table); } break; case 2: temph->type=HTT_R8; break; case 3: temph->type=HTT_R16; break; case 4: temph->type=HTT_R32; break; case 5: temph->type=HTT_R64; break; case 6: temph->type=HTT_SEG; break; } } } else PutAsmError(lx,"Unknown Statement"); } } Free(tempo); LexDel(lx); dd=internal_types_table; while (*dd!=HTT_INVALID) { tempc=CmpClassNew; tempc->type=*dd; dd+=4; tempc->use_cnt=0; tempc->source_link=NULL; tempc->index=NULL; tempc->sub_type=*dd; dd+=4; tempc->size=*dd; dd+=4; tempc->str=ANewStr(dd); dd+=StrLen(tempc->str)+1; AddSysHashEntry(tempc,asm_hash); sys_internal_types[tempc->sub_type]=tempc; if (first) { tempc=MAllocIdentical(tempc); AddSysHashEntry(tempc,adam_tss->hash_table); } } } void LoadCompileSysText() { LoadStr("ST_ERROR",ST_ERROR); LoadStr("ST_WARNING",ST_WARNING); LoadStr("ST_MISSING_SEMICOLON","missing ';' at"); LoadStr("ST_MISSING_EXPRESSION","missing Expression at "); LoadStr("ST_MISSING_RIGHT_PAREN","missing ')' at "); LoadStr("ST_MISSING_RIGHT_BRACKET","missing ']' at "); LoadStr("ST_UNDEFINED_SYMBOL","undefined symbol at "); LoadStr("ST_UNDEFINED_IDENTIFIER","undefined identifier at "); LoadStr("ST_INVALID_CLASS","invalid class at "); LoadStr("ST_INVALID_MEMBER","invalid member at "); LoadStr("ST_EXPECTING_TYPE","expecting type at "); LoadStr("ST_EXPECTING_IDENTIFIER","expecting identifier at "); LoadStr("ST_EXPECTING_RIGHT_PAREN","expecting ')' at "); LoadStr("ST_EXPECTING_LEFT_BRACE","expecting '{' at "); LoadStr("ST_MISSING_RIGHT_BRACE","missing '}' at "); LoadStr("ST_INVALID_LVALUE","invalid lvalue at "); LoadStr("ST_EXPECTING_EQUAL","expecting '=' at "); LoadStr("ST_NOT_POINTER_TYPE","not pointer type at "); LoadStr("ST_EXPECTING_COMMA","expecting ',' at "); LoadStr("ST_EXPECTING_SYS_SYMBOL","expecting System symbol at "); LoadStr("ST_EXPECTING_STR","expecting str at "); LoadStr("ST_MISSING_WHILE","missing 'while' at"); LoadStr("ST_UNKNOWN_STATEMENT","unknown statement at "); LoadStr("ST_ALREADY_ONE_IMMEDIATE","already one immediate at "); LoadStr("ST_SYNTAX_ERROR","syntax error at "); LoadStr("ST_EXPECTING_SCALE_FACTOR","expecting scale factor at "); LoadStr("ST_QUESTION_NOT_ALLOWED","'?' not allowed at "); LoadStr("ST_EXPECTING_LEFT_PAREN","expecting '(' at "); LoadStr("ST_UNDEFINED_DUP_CNT","undefined DUP cnt at "); LoadStr("ST_EXPECTING_COLON","expecting ':' at "); LoadStr("ST_EXPECTING_DOUBLE_COLON","expecting '::' at "); LoadStr("ST_EXPECTING_DOT","expecting '.' at "); LoadStr("ST_EXPECTING_LOCAL_VARIABLE","expecting local variable at "); LoadStr("ST_REDEFINITION","redefinition at "); LoadStr("ST_INVALID_INSTRUCTION","invalid instruction at "); LoadStr("ST_INTERNAL_ERROR","LTintern error at "); LoadStr("ST_BRANCH_OUT_OF_RANGE","branch out of range at "); LoadStr("ST_ATTEMPT_DEFINE_IMPORT","attempt to define import at "); LoadStr("ST_COULD_USE_U1_DISP","could use U1 displacement at "); LoadStr("ST_LINE","line: "); LoadStr("ST_NO_SIZE_SPECIFIED","no size specified at "); LoadList("ST_IT_TYPES","I0\0U0\0I1\0U1\0I2\0U2\0I4\0U4\0I8\0U8\0double\0udouble\0"); LoadList("ST_TY_TYPES","NULL\0IMM\0REG\0DISP\0RIP\0STK\0\0"); LoadList("ST_U1_REGS","AL\0CL\0DL\0BL\0AH\0CH\0DH\0BH\0" "R8u1\0R9u1\0R10u1\0R11u1\0R12u1\0R13u1\0R14u1\0R15u1\0"); LoadList("ST_U2_REGS","AX\0CX\0DX\0BX\0SP\0BP\0SI\0DI\0" "R8u2\0R9u2\0R10u2\0R11u2\0R12u2\0R13u2\0R14u2\0R15u2\0"); LoadList("ST_U4_REGS","EAX\0ECX\0EDX\0EBX\0ESP\0EBP\0ESI\0EDI\0" "R8u4\0R9u4\0R10u4\0R11u4\0R12u4\0R13u4\0R14u4\0R15u4\0"); LoadList("ST_U8_REGS","RAX\0RCX\0RDX\0RBX\0RSP\0RBP\0RSI\0RDI\0" "R8\0R9\0R10\0R11\0R12\0R13\0R14\0R15\0"); LoadList("ST_OPCODE_MODIFIERS","NO\0R\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0RB\0RW\0RD\0"); LoadList("ST_ARGUMENT_TYPES", "NO\0REL8\0REL16\0REL32\0UIMM8\0UIMM16\0UIMM32\0UIMM64\0" "R8\0R16\0R32\0R64\0" "IMM8\0IMM16\0IMM32\0IMM64\0RM8\0RM16\0RM32\0RM64\0" "M8\0M16\0M32\0" "M1616\0M1632\0M16N32\0M16N16\0M32N32\0" "MOFFS8\0MOFFS16\0MOFFS32\0MOFFS64\0" "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0SREG\0" "SS\0DS\0ES\0FS\0GS\0CS\0"); LoadList("ST_SEG_REGS","ES\0CS\0SS\0DS\0FS\0GS\0"); LoadStr("ST_EXPECTING_INTEGER","expecting integer at "); LoadStr("ST_DIVIDE_BY_ZERO","Divide by zero at "); LoadStr("ST_OPT_INTERNAL_ERROR","Compiler Optimization Error at "); LoadStr("ST_UNRESOLVED_REFERENCE","Unresolved Reference:"); LoadStr("ST_NOT_DEFINED","Not Defined"); LoadStr("ST_SCANNING_DIRECTORY","Scanning Directory:"); LoadStr("ST_ASM_NOT_ALLOWED","ASM not allowed"); LoadStr("ST_UNUSED_VAR","Unused Var"); LoadStr("ST_UNUSED_EXTERN","Unused extern"); LoadStr("ST_NOT_ALLOWED_IN_FUNCTION","Not allowed in function"); LoadStr("ST_MISSING_CATCH","missing 'catch' at"); LoadStr("ST_UNDEFINED_GOTO_LABEL","Undefined goto label:"); LoadStr("ST_BREAK_NOT_ALLOWED","'break' not allowed\r\n"); LoadStr("ST_CONTINUE_NOT_ALLOWED","'continue' not allowed\r\n"); LoadStr("ST_ERRORS_WARNINGS","Errors:%04d Warnings:%04d Size:%08X\r\n"); LoadStr("ST_IMPORT_NOT_NEEDED","import not needed at "); LoadStr("ST_EXPECTING_CASE","expecting 'case' at "); LoadStr("ST_CASE_RANGE_ERROR","switch range error at "); LoadStr("ST_LEX_STACK_OVERFLOW","Lex Stack overflow"); LoadStr("ST_STR_DEFAULT","Str defaults not implemented in static mode at "); LoadStr("ST_ASSERT_FAILED","Assert Failed "); LoadStr("ST_ADDRESS_EXTERN","Can't take address of extern function"); $AN,"Anchor for inserting Compiler systext","COMPILE_SYSTEXT"$ LoadList("ST_INTERMEDIATE_CODE", // '*' means it is a dereferrence instruction // '=' means it is an assignment instruction // '^' means it is a compare instruction // '9' param count means variable // 'N' means not constant // param cnt,result cnt,push prior,deref/assign "00..NULL\0" "00..NOP\0" "10..END_EXP\0" "00..LABEL\0" "00..CALL_START\0" "01..CALL_END\0" "00..RETURN_START\0" "00..RETURN_END\0" "00..NOP1\0" "01..IMM\0" "01..DOUBLE\0" "01.NSTR_CONST\0" "01.NABSOLUTE_ADDRESS\0" "01.NTYPE\0" "01.NGET_LABEL\0" "01.NRBP\0" "01.NREG\0" "00.NFS\0" "00.NGS\0" "01.NLEA\0" "01.NMOV\0" "11.NADDRESS\0" "11..COM\0" "11..NOT\0" "11..UNARY_MINUS\0" "11*NDEREF\0" "11*N_PP\0" "11*N_MM\0" "11*NPP_\0" "11*NMM_\0" "21..SHL\0" "21..SHR\0" "21..POWER\0" "21..MUL\0" "21..DIV\0" "21..MOD\0" "21..AND\0" "21..OR\0" "21..XOR\0" "21..ADD\0" "21..SUB\0" "21^.EQUAL_EQUAL\0" "21^.NOT_EQUAL\0" "21^.LESS\0" "21^.GREATER\0" "21^.LESS_EQUAL\0" "21^.GREATER_EQUAL\0" "21..AND_AND\0" "21..OR_OR\0" "21..XOR_XOR\0" "31..COLON\0" "00..QUESTION\0" "21=NASSIGN\0" "21=NSHL_EQUAL\0" "21=NSHR_EQUAL\0" "21=NMUL_EQUAL\0" "21=NDIV_EQUAL\0" "21=NAND_EQUAL\0" "21=NOR_EQUAL\0" "21=NXOR_EQUAL\0" "21=NADD_EQUAL\0" "21=NSUB_EQUAL\0" "90..ADD_RSP\0" "00..ENTER\0" "00..LEAVE\0" "00..RET\0" "00.NCALL\0" "00.NCALL_INDIRECT\0" "00.NCALL_INDIRECT2\0" "00.NIRQ\0" "00..CLI\0" "00..STI\0" "00..DISABLE_CACHE\0" "00..ENABLE_CACHE\0" "00..WBINVD\0" "00..INVD\0" "00.NGET_FLAGS\0" "10.NSET_FLAGS\0" "00.NGET_BASE_PTR\0" "10.NSET_BASE_PTR\0" "00.NGET_STACK_PTR\0" "10.NSET_STACK_PTR\0" "10.NSET_RAX\0" "20.NBT\0" "20.NBTS\0" "20.NBTR\0" "20.NBTC\0" "10.NBSF\0" "10.NBSR\0" "20.NINSQUE\0" "20.NINSQUE_REV\0" "10.NREMQUE\0" "10.NSTRLEN\0" "30.NMEMCPY\0" "30.NMEMSET\0" "10.NINPD\0" "10.NINPW\0" "10.NINP\0" "20.NOUTPD\0" "20.NOUTPW\0" "20.NOUTP\0" "00.NRDTSC\0" "00..JMP\0" "20..SWITCH\0" "10..BR_ZERO\0" "10..BR_NOT_ZERO\0" "20..BR_NOT_EQUAL\0" "20..BR_EQUAL_EQUAL\0" "20..BR_GREATER_EQUAL\0" "20..BR_LESS_EQUAL\0" "20..BR_GREATER\0" "20..BR_LESS\0" "20..BR_OR_OR_ZERO\0" "20..BR_OR_OR_NOT_ZERO\0" "11=.SHL_CONST\0" "11=.SHR_CONST\0" "11=.ADD_CONST\0" "11=.SUB_CONST\0" "00=.PUSH_REGS\0" "00=.POP_REGS\0" "20..BR_BT\0" "20..BR_BTS\0" "20..BR_BTR\0" "20..BR_BTC\0" "20..BR_NOT_BT\0" "20..BR_NOT_BTS\0" "20..BR_NOT_BTR\0" "20..BR_NOT_BTC\0" "00..CALL_END2\0" "20.NLBTS\0" "20.NLBTR\0" "20.NLBTC\0" "20.NBR_LBTS\0" "20.NBR_LBTR\0" "20.NBR_LBTC\0" "20.NBR_NOT_LBTS\0" "20.NBR_NOT_LBTR\0" "20.NBR_NOT_LBTC\0" "20..BR_AND_AND_ZERO\0" "20..BR_AND_AND_NOT_ZERO\0" "20..BR_AND_ZERO\0" "20..BR_AND_NOT_ZERO\0" "21=NMOD_EQUAL\0" "00.NCALL_EXTERN\0" "10.NABSI8\0" "01..PUSH_CMP\0" "10.NPREEMPT\0" ); } void FillCompilerTables() { I1 *st; U8 i,k; U2 *u; U4 *d4; assign_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); deref_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); cmp_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); not_constant_bitmap=MAllocZ((EC_NUM_ENTRIES+7)>>3); cmp_param_cnt=MAllocZ(EC_NUM_ENTRIES); cmp_result_cnt=MAllocZ(EC_NUM_ENTRIES); st=SysText("ST_INTERMEDIATE_CODE"); for (i=0;i'; u['/']='*'; u[':']=256*TK_DOUBLE_COLON+':'; u['<']=256*TK_LESS_EQUAL+'='; u['=']=256*TK_EQUAL_EQUAL+'='; u['>']=256*TK_GREATER_EQUAL+'='; u['^']=256*TK_XOR_EQUAL+'='; u['|']=256*TK_OR_OR+'|'; u['%']=256*TK_MOD_EQUAL+'='; u=MAllocZ(sizeof(U2)*TK_NUM_TK); duel_I1_tokens2=u; u['&']=256*TK_AND_EQUAL+'='; u['+']=256*TK_ADD_EQUAL+'='; u['-']=256*TK_MINUS_MINUS+'-'; u['/']='/'; u['<']=256*TK_SHL+'<'; u['>']=256*TK_SHR+'>'; u['^']=256*TK_XOR_XOR+'^'; u['|']=256*TK_OR_EQUAL+'='; u=MAllocZ(sizeof(U2)*TK_NUM_TK); duel_I1_tokens3=u; u['-']=256*TK_SUB_EQUAL+'='; u['/']=256*TK_DIV_EQUAL+'='; u['>']=256*TK_CAST+'<'; //$AN,"","OP_Precidence"$Here the operator precidences are //defined. d4=MAllocZ(sizeof(U4)*TK_NUM_TK); unary_ops_table=d4; d4['~']=0x10000+EC_COM; d4['!']=0x10000+EC_NOT; d4['-']=0x10000+EC_UNARY_MINUS; d4['&']=0x10000+EC_ADDRESS; d4['*']=0x10000+EC_DEREF; d4=MAllocZ(sizeof(U4)*TK_NUM_TK); binary_ops_table=d4; //There is an exponential operator and //shift instructions are rightfully //the precidence of exponentials. d4['`'] =0x20000+EC_POWER; d4[TK_SHL] =0x20000+EC_SHL; d4[TK_SHR] =0x20000+EC_SHR; d4['*'] =0x30000+EC_MUL; d4['/'] =0x30000+EC_DIV; d4['%'] =0x30000+EC_MOD; //$FG,2$&$FG$ is higher precidence $FG,2$|$FG$, like in logic d4['&'] =0x40000+EC_AND; d4['|'] =0x50000+EC_OR; d4['^'] =0x50000+EC_XOR; d4['+'] =0x60000+EC_ADD; d4['-'] =0x60000+EC_SUB; d4[TK_EQUAL_EQUAL] =0x70000+EC_EQUAL_EQUAL; d4[TK_NOT_EQUAL] =0x70000+EC_NOT_EQUAL; d4['<'] =0x70000+EC_LESS; d4['>'] =0x70000+EC_GREATER; d4[TK_LESS_EQUAL] =0x70000+EC_LESS_EQUAL; d4[TK_GREATER_EQUAL]=0x70000+EC_GREATER_EQUAL; //$FG,2$&&$FG$ is higher precidence $FG,2$||$FG$, like in logic d4[TK_AND_AND] =0x80000+EC_AND_AND; d4[TK_OR_OR] =0x90000+EC_OR_OR; d4[TK_XOR_XOR] =0x90000+EC_XOR_XOR; d4[':'] =0xA0000+EC_COLON; d4['?'] =0xA0000+EC_QUESTION; d4['='] =0x100000+EC_ASSIGN; d4[TK_SHL_EQUAL]=0x100000+EC_SHL_EQUAL; d4[TK_SHR_EQUAL]=0x100000+EC_SHR_EQUAL; d4[TK_MUL_EQUAL]=0x100000+EC_MUL_EQUAL; d4[TK_DIV_EQUAL]=0x100000+EC_DIV_EQUAL; d4[TK_MOD_EQUAL]=0x100000+EC_MOD_EQUAL; d4[TK_AND_EQUAL]=0x100000+EC_AND_EQUAL; d4[TK_OR_EQUAL] =0x100000+EC_OR_EQUAL; d4[TK_XOR_EQUAL]=0x100000+EC_XOR_EQUAL; d4[TK_ADD_EQUAL]=0x100000+EC_ADD_EQUAL; d4[TK_SUB_EQUAL]=0x100000+EC_SUB_EQUAL; } void InitCompiler(BoolU4 first) { is_first_compiler=first; cmp_do_not_write_to_disk=FALSE; if (first) ext[EXT_CMP_EXE_BLK]=&CmpParseExeBlk; LoadCompileSysText; FillCompilerTables; MemSet(&opt_nop,0,sizeof(IntermediateCode)); opt_nop.ic_class=sys_internal_types[IT_I8]; opt_nop.ic_opcode=EC_NOP; LoadAsmHash(first); }