ClassStruct *CmpClassNew() { ClassStruct *result=MAllocZ(sizeof(ClassStruct)*5), *tempc=result; tempc->last_in_member_list=&tempc->member_list; tempc->type=HTT_CLASS; tempc->sub_type=IT_PTR; tempc->ptr_cnt=0; tempc+=sizeof(ClassStruct); tempc->type=HTT_CLASS; tempc->sub_type=IT_PTR; tempc->size=sizeof(void *); tempc->ptr_cnt=1; tempc+=sizeof(ClassStruct); tempc->type=HTT_CLASS; tempc->sub_type=IT_PTR; tempc->size=sizeof(void *); tempc->ptr_cnt=2; tempc+=sizeof(ClassStruct); tempc->type=HTT_CLASS; tempc->sub_type=IT_PTR; tempc->size=sizeof(void *); tempc->ptr_cnt=3; tempc+=sizeof(ClassStruct); tempc->type=HTT_CLASS; tempc->sub_type=IT_PTR; tempc->size=sizeof(void *); tempc->ptr_cnt=4; return result; } void AddUnresolved(AsmCtrlStruct *a,U1 *exp,I8 type,U8 ip,U8 rel_ip, LexUndefEntry *undef_hash,I8 line_num,BoolU4 U1_avail,BoolU4 glbl) { AsmUnresolvedRef *tempu=MAlloc(sizeof(AsmUnresolvedRef)); tempu->exp=exp; tempu->type=type; tempu->ip=ip; tempu->rel_ip=rel_ip; tempu->undef_hash=undef_hash; tempu->literal=FALSE; tempu->line_num=line_num; tempu->U1_avail=U1_avail; tempu->str=NULL; if (glbl) { tempu->next=a->glbl_unresolved; a->glbl_unresolved=tempu; if (undef_hash->hash->type & HTT_IMPORT) { tempu->str=NewStr(undef_hash->hash->str); if (undef_hash->hash->type & HTT_LITERAL) tempu->literal=TRUE; } } else { tempu->next=a->local_unresolved; a->local_unresolved=tempu; a->has_locals=TRUE; } } void AsmListLine(LexStruct *lx) { I8 i; AsmCtrlStruct *a=lx->a; LexFileStruct *tempf=lx->cur_lfn; LtfEntry *cl=tempf->line_start,*cl3; if (a->list && a->last_lfn==tempf && cl) { if (cl3=a->last_line_listed) { while (cl3->yy) { for (i=a->display_col;i<8;i++) cout " "; a->display_col=0; PrintF("%08X ",a->last_ip); cl3=LexPutLine(lx,cl3); } a->last_line_listed=cl3; } else a->last_line_listed=cl; } else { a->last_line_listed=NULL; a->last_lfn=tempf; } a->last_ip=a->ip; } void AsmStoreCodeU1(LexStruct *lx,U1 b) { AsmCtrlStruct *a=lx->a; I8 i=a->ip>>ASM_CODE_BLK_BITS; AsmCodeBlk *tempc=a->code; while (i--) if (!(tempc=tempc->next)) { i=a->ip>>ASM_CODE_BLK_BITS+1; tempc=&a->code; while (i--) { if (!*tempc) *tempc=MAllocZ(sizeof(AsmCodeBlk)); tempc=tempc->next; } break; } tempc->body[a->ip++ & (ASM_CODE_BLK_SIZE-1)]=b; if (a->list) { PrintF("%02X ",b); a->display_col++; if (a->display_col>8) { a->display_col=0; AsmListLine(lx); } } if (a->ip>a->num_code_U1s) a->num_code_U1s=a->ip; } void AsmStoreCodeU4(LexStruct *lx,U4 d) { AsmCtrlStruct *a=lx->a; I8 i=a->ip>>ASM_CODE_BLK_BITS, j=(a->ip+sizeof(U4))>>ASM_CODE_BLK_BITS; U4 *dd; AsmCodeBlk *tempc=a->code; if (i!=j) { for (i=0;icode; while (i--) if (!(tempc=tempc->next)) { i=a->ip>>ASM_CODE_BLK_BITS+1; tempc=&a->code; while (i--) { if (!*tempc) *tempc=MAllocZ(sizeof(AsmCodeBlk)); tempc=tempc->next; } break; } dd=tempc->body+(a->ip&(ASM_CODE_BLK_SIZE-1)); *dd=d; a->ip+=sizeof(U4); if (a->list) { PrintF("%08X ",d); a->display_col+=sizeof(U4); if (a->display_col>8) { a->display_col=0; AsmListLine(lx); } } if (a->ip>a->num_code_U1s) a->num_code_U1s=a->ip; } void AsmStoreCodeU8(LexStruct *lx,U8 d) { AsmCtrlStruct *a=lx->a; I8 i=a->ip>>ASM_CODE_BLK_BITS, j=(a->ip+sizeof(U8))>>ASM_CODE_BLK_BITS; U8 *dd; AsmCodeBlk *tempc=a->code; if (i!=j) { for (i=0;icode; while (i--) if (!(tempc=tempc->next)) { i=a->ip>>ASM_CODE_BLK_BITS+1; tempc=&a->code; while (i--) { if (!*tempc) *tempc=MAllocZ(sizeof(AsmCodeBlk)); tempc=tempc->next; } break; } dd=tempc->body+(a->ip&(ASM_CODE_BLK_SIZE-1)); *dd=d; a->ip+=sizeof(U8); if (a->list) { PrintF("%016X ",d); a->display_col+=sizeof(U8); if (a->display_col>8) { a->display_col=0; AsmListLine(lx); } } if (a->ip>a->num_code_U1s) a->num_code_U1s=a->ip; } void AsmStoreCodeU1At(LexStruct *lx,U1 b,I8 ip) { AsmCtrlStruct *a=lx->a; I8 i=ip>>ASM_CODE_BLK_BITS+1; AsmCodeBlk *tempc=&a->code; while (i--) { if (!*tempc) { *tempc=MAlloc(sizeof(AsmCodeBlk)); **tempc=NULL; } tempc=tempc->next; } tempc->body[ip & (ASM_CODE_BLK_SIZE-1)]=b; if (ip+1>a->num_code_U1s) a->num_code_U1s=ip+1; } I8 AsmEvalExpression(LexStruct *lx) { U1 *exp; I8 result=0; lx->undef_hash_entry=NULL; lx->flags&=~(LF_UNRESOLVED_LOCAL+LF_UNRESOLVED_GLBL); lx->absolute_address_cnt=0; if (!GetExpression(lx,&exp)) LexSkipEol(lx); else { if (!(lx->flags & (LF_UNRESOLVED_LOCAL|LF_UNRESOLVED_GLBL))) { result=Call(exp); DelExpression(exp); } else PutAsmError(lx,"ST_UNDEFINED_SYMBOL"); } return result; } void ResolveLocals(LexStruct *lx) { AsmCtrlStruct *a=lx->a; AsmUnresolvedRef *tempu=a->local_unresolved,*tempu1; I8 result=0; LexUndefEntry *templu; BoolU4 undefined; I1 *label=NULL; if (!a->has_locals) return; while (tempu) { undefined=FALSE; tempu1=tempu->next; templu=tempu->undef_hash; while (templu) { if (templu->hash->type & (HTT_UNRESOLVED_LOCAL | HTT_UNRESOLVED_GLBL)) { PrintFErr("%S%S%04d ","ST_UNDEFINED_SYMBOL","ST_LINE",tempu->line_num); if (a->last_label) cout a->last_label," "; coutln templu->hash->str; lx->error_cnt++; undefined=TRUE; } else label=templu->hash->str; templu=templu->next; } if (!undefined) { result=Call(tempu->exp); if (!(tempu->type & 1)) { result-=tempu->rel_ip; if (tempu->type==EIE_REL_U1 && (resultMAX_I1) || tempu->type==EIE_REL_U2 && (resultMAX_I2) ) { PrintFErr("%S%S%04d ","ST_BRANCH_OUT_OF_RANGE","ST_LINE",tempu->line_num); if (a->last_label) PrintF("%s ",a->last_label); if (label) cout label; CrLf; lx->error_cnt++; } if (tempu->U1_avail && tempu->type>EIE_LIT_U1 && (result>=-124 && result<=123)) { PrintFWarn("%S%S%04d ","ST_COULD_USE_U1_DISP","ST_LINE",tempu->line_num); if (a->last_label) PrintF("%s ",a->last_label); if (label) cout label; CrLf; } } AsmStoreCodeU1At(lx,result.u1[0],tempu->ip); if (tempu->type>=EIE_REL_U2) AsmStoreCodeU1At(lx,result.u1[1],tempu->ip+1); if (tempu->type>=EIE_REL_U4) { AsmStoreCodeU1At(lx,result.u1[2],tempu->ip+2); AsmStoreCodeU1At(lx,result.u1[3],tempu->ip+3); } } DelExpression(tempu->exp); DelLinkedList(tempu->undef_hash); Free(tempu); tempu=tempu1; } DelHashTable(a->local_hash); a->local_hash=NewHashTable(16); a->local_hash->next=a->glbl_hash; lx->hash_table_list=a->local_hash; lx->local_hash_table=a->local_hash; a->local_unresolved=NULL; a->has_locals=FALSE; } void ResolveGlbls(LexStruct *lx,ExeStruct *e) { AsmCtrlStruct *a=lx->a; ClassStruct *tempc; GlblVarStruct *tempg; AsmUnresolvedRef *tempu=a->glbl_unresolved,*tempu1; I8 result=0; ExeImportExportStruct *tempe,*tempe1; LexUndefEntry *templu; I8 i,j; SysHashEntry *temph; I1 *label; BoolU4 undefined; ExternUsage *tempeu,*tempeu1; while (tempu) { label=NULL; undefined=FALSE; tempu1=tempu->next; templu=tempu->undef_hash; while (templu) { if (templu->hash->type & (HTT_UNRESOLVED_LOCAL | HTT_UNRESOLVED_GLBL)) { if (!(templu->hash->type & HTT_IMPORT)) { PrintFErr("%S%S%04d ","ST_UNDEFINED_SYMBOL","ST_LINE",tempu->line_num); cout templu->hash->str,"\r\n"; lx->error_cnt++; } undefined=TRUE; } else label=templu->hash->str; templu=templu->next; } if (undefined) { templu=tempu->undef_hash; if (templu->hash->type & HTT_IMPORT) { tempe=MAllocZ(sizeof(ExeImportExportStruct)); tempe->next=templu->hash->user_data1; tempe->str=NULL; templu->hash->user_data1=tempe; tempe->ip=tempu->ip; tempe->type=tempu->type; } } else { result=Call(tempu->exp); if (!(tempu->type & 1)) { result-=tempu->rel_ip; if ((tempu->type==EIE_REL_U1 && (resultMAX_I1)) || tempu->type==EIE_REL_U2 && (resultMAX_I2)) { PrintFErr("%S%S%04d ","ST_BRANCH_OUT_OF_RANGE","ST_LINE",tempu->line_num); if (label) cout label; CrLf; lx->error_cnt++; } if (tempu->U1_avail && tempu->type>EIE_LIT_U1 && (result>=-124 && result<=123)) { PrintFWarn("%S%S%04d ","ST_COULD_USE_U1_DISP","ST_LINE",tempu->line_num); if (a->last_label) PrintF("%s ",a->last_label); if (label) cout label; CrLf; } } AsmStoreCodeU1At(lx,result.u1[0],tempu->ip); if (tempu->type>=EIE_REL_U2) AsmStoreCodeU1At(lx,result.u1[1],tempu->ip+1); if (tempu->type>=EIE_REL_U4) { AsmStoreCodeU1At(lx,result.u1[2],tempu->ip+2); AsmStoreCodeU1At(lx,result.u1[3],tempu->ip+3); } } DelExpression(tempu->exp); DelLinkedList(tempu->undef_hash); Free(tempu); tempu=tempu1; } tempe1=&e->ie; while (tempe1->next) tempe1=tempe1->next; for (i=0;i<=a->glbl_hash->mask;i++) { temph=a->glbl_hash->body[i]; while (temph) { if (temph->type & HTT_IMPORT && temph->use_cnt) { if (temph->type & HTT_FUNCTION) { tempe=MAllocZ(sizeof(ExeImportExportStruct)); tempe->type=EIE_LIT_U4; tempc=temph; tempe->str=(tempc->import_name) ? NewStr(tempc->import_name):NewStr(tempc->str); tempe->ip=tempc->executable_address; tempe1->next=tempe; tempe1=tempe; } else if (temph->type & HTT_GLBL_VAR) { tempe=MAllocZ(sizeof(ExeImportExportStruct)); tempe->type=EIE_LIT_U4; tempg=temph; if (tempg->import_name) tempe->str=NewStr(tempg->import_name); else tempe->str=NewStr(tempg->str); tempe->ip=tempg->data_address; tempe1->next=tempe; tempe1=tempe; } else { tempe=temph->user_data1; if (tempe) { tempe1->next=tempe; tempe->str=NewStr(temph->str); while (tempe1->next) tempe1=tempe1->next; } } } else if (temph->type & HTT_EXPORT) { if (temph->type & HTT_UNRESOLVED_GLBL) { PrintFErr("%S%s\r\n","ST_UNDEFINED_SYMBOL",temph->str); lx->error_cnt++; } else { tempe=MAlloc(sizeof(ExeImportExportStruct)); tempe->type=EIE_REL_EXPORT; if (temph->type & HTT_FUNCTION) { tempc=temph; tempe->ip=tempc->executable_address; tempeu=tempc->ext_list; while (tempeu) { tempeu1=tempeu->next; j=tempc->executable_address-(tempeu->ip+4); AsmStoreCodeU1At(lx,j.u1[0],tempeu->ip); AsmStoreCodeU1At(lx,j.u1[1],tempeu->ip+1); AsmStoreCodeU1At(lx,j.u1[2],tempeu->ip+2); AsmStoreCodeU1At(lx,j.u1[3],tempeu->ip+3); Free(tempeu); tempeu=tempeu1; } } else if (temph->type & HTT_GLBL_VAR) { tempg=temph; tempe->ip=tempg->data_address; } else tempe->ip=temph->user_data0; if (temph->type & HTT_LITERAL) tempe->type++; *tempe1=tempe; tempe->next=NULL; tempe1=tempe; tempe->str=NewStr(temph->str); } } temph=temph->next; } } } BoolU8 ParseAsmImm(LexStruct *lx,AsmCtrlStruct *aa,AsmArgStruct *a,U8 ip) { if (a->imm_or_off_present) { PutAsmError(lx,"ST_ALREADY_ONE_IMMEDIATE"); return FALSE; } else { a->imm_or_off_present=TRUE; a->undef_local=NULL; a->undef_glbl=NULL; lx->instruction_pointer=ip; lx->undef_hash_entry=NULL; lx->absolute_address_cnt=0; lx->flags&=~(LF_UNRESOLVED_LOCAL+LF_UNRESOLVED_GLBL); if (!GetExpression(lx,&a->exp)) LexSkipEol(lx); else { if (!(lx->flags & (LF_UNRESOLVED_LOCAL|LF_UNRESOLVED_GLBL))) { a->imm=Call(a->exp); a->undef_glbl=lx->undef_hash_entry; lx->undef_hash_entry=NULL; DelExpression(a->exp); a->exp=NULL; } else { if (lx->flags & LF_UNRESOLVED_GLBL) { a->undef_glbl=lx->undef_hash_entry; lx->undef_hash_entry=NULL; aa->has_locals=TRUE; } else if (lx->flags & LF_UNRESOLVED_LOCAL) { a->undef_local=lx->undef_hash_entry; lx->undef_hash_entry=NULL; } } } } return TRUE; } void ParseAsmArg(LexStruct *lx,AsmCtrlStruct *aa,AsmArgStruct *a,U8 ip) { I8 i,temp; a->size=0; a->absolute_address_cnt=0; a->seg=16; a->reg1=16; a->reg2=16; a->imm=0; a->scale=1; a->indirect=FALSE; a->imm_or_off_present=FALSE; a->undef_local=NULL; a->undef_glbl=NULL; a->just_seg=FALSE; a->exp=NULL; while (TRUE) { if (lx->token==TK_IDENT) { if (lx->hash_entry) { if (lx->hash_entry->type==HTT_R8) { a->size=1; a->reg1=lx->hash_entry->user_data0; Lex(lx); return; } else if (lx->hash_entry->type==HTT_R16) { a->size=2; a->reg1=lx->hash_entry->user_data0; Lex(lx); return; } else if (lx->hash_entry->type==HTT_R32) { a->size=4; a->reg1=lx->hash_entry->user_data0; Lex(lx); return; } else if (lx->hash_entry->type==HTT_R64) { a->size=8; a->reg1=lx->hash_entry->user_data0; Lex(lx); return; } else if (lx->hash_entry->type==HTT_SEG) { a->seg=lx->hash_entry->user_data0; if (Lex(lx)!=':') { a->just_seg=TRUE; return; } else Lex(lx); //skip ":" } else if (lx->hash_entry->type==HTT_KEYWORD) { i=lx->hash_entry->user_data0; if (i==AKW_U1) { Lex(lx); //skip keyword a->size=1; } else if (i==AKW_U2) { Lex(lx); //skip keyword a->size=2; } else if (i==AKW_U4) { Lex(lx); //skip keyword a->size=4; } else if (i==AKW_U8) { Lex(lx); //skip keyword a->size=8; } else { PutAsmError(lx,"ST_SYNTAX_ERROR"); return; } } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; if (lx->token!='[') return; } } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; if (lx->token!='[') return; } } else if (lx->token=='[') { a->indirect=TRUE; Lex(lx); // skip [ while (lx->token && lx->token!=']') { if (lx->token==TK_IDENT) { if (lx->hash_entry) { if (lx->hash_entry->type==HTT_R16 || lx->hash_entry->type==HTT_R32 || lx->hash_entry->type==HTT_R64) { if (a->reg1==16) a->reg1=lx->hash_entry->user_data0; else a->reg2=lx->hash_entry->user_data0; Lex(lx); } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; } } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; } } else if (lx->token=='*') { if (Lex(lx)!=TK_INTEGER) PutAsmError(lx,"ST_EXPECTING_SCALE_FACTOR"); else { a->scale=lx->cur_i; Lex(lx); //skip scale if (a->reg2!=16) { temp=a->reg1; a->reg1=a->reg2; a->reg2=temp; } } } else if (lx->token=='+') { Lex(lx); //skip '+' } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; } } if (lx->token==']') { Lex(lx); //skip ] return; } else PutAsmError(lx,"ST_MISSING_RIGHT_BRACKET"); } else { ParseAsmImm(lx,aa,a,ip); a->absolute_address_cnt=lx->absolute_address_cnt; if (lx->token!='[') return; } } } void AsmMakeArgMask(AsmArgStruct *a,U8 *mask) { if (a->just_seg) { switch (a->seg) { case 0: *mask=1<size) { case 0: *mask=0x3FF07FFFFE; break; case 1: *mask=0x1110111112; break; case 2: *mask=0x2220222224; break; case 4: *mask=0x0440444448; break; case 8: *mask=0x0880088880; break; } if (a->reg1!=16 && a->imm_or_off_present && !a->imm) { if (!a->undef_glbl && !a->undef_local) a->imm_or_off_present=FALSE; //Zero displacement } if (a->reg2!=16 || a->scale!=1) { *mask&= 0x00000F0000; return; } if (a->indirect) { if (a->imm_or_off_present) *mask&=0x00FFFF0000; else *mask&=0x000FFF0000; } else { if (a->imm_or_off_present) *mask&=0x000F80F0FE; else *mask&=0x3F0F8F0F00; } if (a->seg!=16) *mask&= 0x00FFFF0000; if (a->reg1==16) { if (a->indirect) *mask&=0x00FFFF0000; else if (MIN_I1<=a->imm<=MAX_I1) *mask&=0x000000F0FE; else if (MIN_I1<=a->imm<=MAX_U1) *mask&=0x000000E0FE; else if (MIN_I2<=a->imm<=MAX_I2) *mask&=0x000000E0EE; else if (MIN_I2<=a->imm<=MAX_U2) *mask&=0x000000C0EE; else if (MIN_I4<=a->imm<=MAX_I4) *mask&=0x000000C0CE; else if (MIN_I4<=a->imm<=MAX_U4) *mask&=0x00000080CE; else *mask&=0x000000808E; } else *mask&= 0x3F007F0F00; if (a->reg1!=0) *mask&= 0x30FFFFFFFF; if (a->reg1!=1) *mask&= 0x2FFFFFFFFF; if (a->reg1!=2) *mask&= 0x1FFFFFFFFF; } BoolU8 AsmStoreNum(LexStruct *lx,AsmCtrlStruct *a,I8 num,BoolU4 is_question,I8 num_U1s,I8 cnt, I8 num_ip_rel,I8 num_lit, U1 *num_exp,LexUndefEntry *num_local_hash,LexUndefEntry *num_glbl_hash, BoolU4 U1_avail,U8 abs_add_cnt) { I8 i; ExeAbsoluteAddressStruct *tempa; if (!num_lit) num-=num_ip_rel; for (i=0;iip,num_ip_rel, num_local_hash,LexLineNum(lx),U1_avail,FALSE); else if (num_glbl_hash) AddUnresolved(a,num_exp,EIE_REL_U1+num_lit,a->ip,num_ip_rel, num_glbl_hash,LexLineNum(lx),U1_avail,TRUE); else { if (!num_lit && (numMAX_I1)) { // LexPop(lx); PutAsmError(lx,"ST_BRANCH_OUT_OF_RANGE"); a->ip++; return FALSE; } } if (is_question) a->ip++; else AsmStoreCodeU1(lx,num.u1[0]); } else if (num_U1s==2) { if (num_local_hash) AddUnresolved(a,num_exp,EIE_REL_U2+num_lit,a->ip,num_ip_rel, num_local_hash,LexLineNum(lx),U1_avail,FALSE); else if (num_glbl_hash) AddUnresolved(a,num_exp,EIE_REL_U2+num_lit,a->ip,num_ip_rel, num_glbl_hash,LexLineNum(lx),U1_avail,TRUE); else { if (!num_lit && (num MAX_I2)) { // LexPop(lx); PutAsmError(lx,"ST_BRANCH_OUT_OF_RANGE"); a->ip+=2; return FALSE; } } if (is_question) a->ip+=2; else { AsmStoreCodeU1(lx,num.u1[0]); AsmStoreCodeU1(lx,num.u1[1]); } if (U1_avail && !num_local_hash && !num_glbl_hash && !num_lit && num>=-124 && num<=123) { // LexPop(lx); PutAsmWarning(lx,"ST_COULD_USE_U1_DISP"); return FALSE; } } else if (num_U1s==4) { if (num_local_hash) AddUnresolved(a,num_exp,EIE_REL_U4+num_lit,a->ip,num_ip_rel, num_local_hash,LexLineNum(lx),U1_avail,FALSE); else if (num_glbl_hash) AddUnresolved(a,num_exp,EIE_REL_U4+num_lit,a->ip,num_ip_rel, num_glbl_hash,LexLineNum(lx),U1_avail,TRUE); if (num_lit && abs_add_cnt & 1) { tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct)); tempa->next=a->absolutes; a->absolutes=tempa; tempa->ip=a->ip; } if (is_question) a->ip+=sizeof(U4); else AsmStoreCodeU4(lx,num.u4[0]); if (U1_avail && !num_local_hash && !num_glbl_hash && !num_lit && num>=-124 && num<=123) { // LexPop(lx); PutAsmWarning(lx,"ST_COULD_USE_U1_DISP"); return FALSE; } } else if (num_U1s==8) { //dbgo if (num_local_hash) AddUnresolved(a,num_exp,EIE_REL_U4+num_lit,a->ip,num_ip_rel, num_local_hash,LexLineNum(lx),U1_avail,FALSE); else if (num_glbl_hash) AddUnresolved(a,num_exp,EIE_REL_U4+num_lit,a->ip,num_ip_rel, num_glbl_hash,LexLineNum(lx),U1_avail,TRUE); if (num_lit && abs_add_cnt & 1) { tempa=MAllocZ(sizeof(ExeAbsoluteAddressStruct)); tempa->next=a->absolutes; a->absolutes=tempa; tempa->ip=a->ip; } if (is_question) a->ip+=sizeof(U8); else AsmStoreCodeU8(lx,num); if (U1_avail && !num_local_hash && !num_glbl_hash && !num_lit && num>=-124 && num<=123) { // LexPop(lx); PutAsmWarning(lx,"ST_COULD_USE_U1_DISP"); return FALSE; } } } return TRUE; } BoolU8 AsmCodeInstruction(LexStruct *lx,AsmCtrlStruct *a, OpcodeHashEntry *tempo,I8 argcnt) { I8 i,j,a1,a2,om,seg; U8 arg1mask,arg2mask; AsmArgStruct *tempa1,*tempa2; BoolU4 ModrM_complete,U1_avail=FALSE,found_second_possible=FALSE; I8 U1_cnt; U1 last_opcode_U1; InstructionEntry *tempi; BoolU4 has_ModrM; U1 ModrM; BoolU4 has_SIB; U1 SIB,REX; BoolU4 has_address_prefix; BoolU4 has_operand_prefix; BoolU4 is_default; I8 disp,disp_U1s,disp_ip_rel,disp_lit,disp_abs_cnt; I8 imm, imm_U1s, imm_ip_rel, imm_lit,imm_abs_cnt; U1 *disp_exp,*imm_exp; LexUndefEntry *disp_local_hash,*disp_glbl_hash; LexUndefEntry *imm_local_hash,*imm_glbl_hash; I8 best_U1_cnt=255; U1 blast_opcode_U1; InstructionEntry *btempi; BoolU4 bhas_ModrM; U1 bModrM; BoolU4 bhas_SIB; U1 bSIB,bREX; BoolU4 bhas_address_prefix; BoolU4 bhas_operand_prefix; BoolU4 bis_default; I8 bdisp,bdisp_U1s,bdisp_ip_rel,bdisp_lit,bdisp_abs_cnt; I8 bimm, bimm_U1s, bimm_ip_rel, bimm_lit,bimm_abs_cnt; U1 *bdisp_exp,*bimm_exp; LexUndefEntry *bdisp_local_hash,*bdisp_glbl_hash; LexUndefEntry *bimm_local_hash,*bimm_glbl_hash; if (argcnt>0) AsmMakeArgMask(&a->arg1,&arg1mask); else arg1mask=1; if (argcnt>1) AsmMakeArgMask(&a->arg2,&arg2mask); else arg2mask=1; for (i=0;iinstruction_entry_cnt;i++) { tempi=&tempo->ins[i]; if (tempi->arg1==ARGT_REL8 || tempi->arg2==ARGT_REL8) U1_avail=TRUE; if (Bt(&arg1mask,tempi->arg1) && Bt(&arg2mask,tempi->arg2)) { ModrM_complete=FALSE; last_opcode_U1=0; has_ModrM=FALSE; ModrM=0; has_SIB=FALSE; SIB=0; has_address_prefix=FALSE; has_operand_prefix=FALSE; is_default=(tempi->flags & IEF_DEFAULT) ? TRUE:FALSE; if (a->seg_size==64) { REX=0x40; if (tempi->flags & IEF_48_REX) REX=0x48; else if (tempi->flags & IEF_NO_REX) REX=0x00; } else REX=0x00; disp=0; disp_U1s=0; disp_ip_rel=0; disp_lit=1; imm=0; imm_U1s=0; imm_ip_rel=0; imm_lit=1; disp_exp=NULL; imm_exp=NULL; disp_local_hash=NULL; disp_glbl_hash=NULL; disp_abs_cnt=0; imm_local_hash=NULL; imm_glbl_hash=NULL; imm_abs_cnt=0; om=tempi->opcode_modifier; a1=tempi->arg1; a2=tempi->arg2; tempa1=&a->arg1; tempa2=&a->arg2; last_opcode_U1=tempi->opcode[tempi->opcode_cnt-1]; if (tempi->slash_value<8) { ModrM+=tempi->slash_value<<3; has_ModrM=TRUE; } if ((a->seg_size==16 && tempi->flags & IEF_OP_SIZE32) || (a->seg_size!=16 && tempi->flags & IEF_OP_SIZE16)) has_operand_prefix=TRUE; if (om==OM_IB) imm_U1s=1; else if (om==OM_IW) imm_U1s=2; else if (om==OM_ID) imm_U1s=4; if (om==OM_CB) { imm_U1s=1; imm_lit=0; } else if (om==OM_CW) { imm_U1s=2; imm_lit=0; } else if (om==OM_CD) { imm_U1s=4; imm_lit=0; } if (argcnt==1) { if (best_U1_cnt!=255 && !found_second_possible && !bis_default) { found_second_possible=TRUE; if (!a->arg1.size) PrintFWarn("%S%s,%04d\r\n","ST_NO_SIZE_SPECIFIED", lx->cur_lfn->name,lx->cur_lfn->line_num-1); } if (tempi->flags & IEF_PLUS_OPCODE) { last_opcode_U1=last_opcode_U1+tempa1->reg1&7; if (tempa1->reg1>7) REX|=1; } if (a1==ARGT_R64 || a1==ARGT_RM64) REX|=8; if (a1>=ARGT_RM8 && a1<=ARGT_RM64) { if (a->seg_size==16) has_address_prefix=TRUE; has_ModrM=TRUE; if (tempa1->imm_or_off_present && tempa1->indirect && tempa1->reg1==16) { ModrM=ModrM+5; disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_U1s=4; disp_abs_cnt=tempa1->absolute_address_cnt; if (a->seg_size==64) disp_lit=0; } else { if (tempa1->reg2==16 && tempa1->scale==1) { ModrM+=tempa1->reg1&7; if (tempa1->reg1>7) REX|=1; } else { ModrM+=4; has_SIB=TRUE; if (tempa1->scale==1) SIB=0; else if (tempa1->scale==2) SIB=0x40; else if (tempa1->scale==4) SIB=0x80; else if (tempa1->scale==8) SIB=0xC0; if (tempa1->reg2==16) { ModrM_complete=TRUE; SIB+=((tempa1->reg1&7)<<3)+5; if (tempa1->reg1>7) REX|=2; disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_U1s=4; disp_abs_cnt=tempa1->absolute_address_cnt; } else { SIB+=((tempa1->reg1&7)<<3)+tempa1->reg2&7; if (tempa1->reg1>7) REX|=2; if (tempa1->reg2>7) REX|=1; if (tempa1->reg2==5 && !tempa1->imm_or_off_present && tempa1->indirect) { ModrM+=0x40; disp_U1s=1; ModrM_complete=TRUE; } } } if (!ModrM_complete) { if (tempa1->imm_or_off_present) { disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_abs_cnt=tempa1->absolute_address_cnt; if (!disp_exp && MIN_I1<=disp<=MAX_I1) { ModrM+=0x40; disp_U1s=1; } else if (a->seg_size==16) { ModrM+=0x80; disp_U1s=2; } else { ModrM+=0x80; disp_U1s=4; } } else if (!tempa1->indirect) { has_address_prefix=FALSE; ModrM+=0xC0; } else { if (tempa1->reg1==5) { ModrM+=0x40; disp_U1s=1; } } } } } else if (a1>=ARGT_REL8 && a1<=ARGT_REL32 || a1>=ARGT_IMM8 && a1<=ARGT_IMM64 || a1>=ARGT_UIMM8 && a1<=ARGT_UIMM64) { if (a1==ARGT_IMM64 || a2==ARGT_UIMM64) REX|=8; imm=tempa1->imm; imm_exp=tempa1->exp; imm_local_hash=tempa1->undef_local; imm_glbl_hash=tempa1->undef_glbl; imm_abs_cnt=tempa1->absolute_address_cnt; } } else if (argcnt==2) { if (best_U1_cnt!=255 && !found_second_possible && !bis_default) { found_second_possible=TRUE; if (!a->arg1.size && !a->arg2.size) PrintFWarn("%S%s,%04d\r\n","ST_NO_SIZE_SPECIFIED", lx->cur_lfn->name,lx->cur_lfn->line_num-1); } if (tempi->flags & IEF_PLUS_OPCODE) { if (om>=OM_RB && om<=OM_RD) { last_opcode_U1+=tempa1->reg1&7; if (tempa1->reg1>7) REX|=1; } else if (tempi->slash_value==SV_REGISTER) { if (a1>=ARGT_AL && a1<=ARGT_EAX) { last_opcode_U1+=tempa2->reg1&7; if (tempa2->reg1>7) REX|=1; } else if (a2>=ARGT_AL && a2<=ARGT_EAX) { last_opcode_U1+=tempa1->reg1&7; if (tempa1->reg1>7) REX|=1; } } } if (a1==ARGT_RM64 || a2==ARGT_RM64 || a1==ARGT_R64 || a2==ARGT_R64) REX|=8; if (a1>=ARGT_RM8 && a1<=ARGT_RM64 ||a2>=ARGT_RM8 && a2<=ARGT_RM64) { if (a->seg_size==16) has_address_prefix=TRUE; has_ModrM=TRUE; if (a2>=ARGT_RM8 && a2<=ARGT_RM64) { tempa1=&a->arg2; tempa2=&a->arg1; } if (tempi->slash_value==SV_REGISTER) { if (tempa2->just_seg) ModrM+=(tempa2->seg<<3); else { if (tempa2->reg1==16) { ModrM+=((tempa1->reg1&7)<<3); if (tempa1->reg1>7) REX|=4; } else { ModrM+=((tempa2->reg1&7)<<3); if (tempa2->reg1>7) REX|=4; } } } if (tempa1->reg2==16 && tempa1->scale==1) { if (tempa1->reg1!=16) { ModrM+=tempa1->reg1&7; if (tempa1->reg1>7) REX|=1; } } else { ModrM+=4; has_SIB=TRUE; if (tempa1->scale==1) SIB=0; else if (tempa1->scale==2) SIB=0x40; else if (tempa1->scale==4) SIB=0x80; else if (tempa1->scale==8) SIB=0xC0; if (tempa1->reg2==16) { ModrM_complete=TRUE; SIB+=((tempa1->reg1&7)<<3)+5; if (tempa1->reg1>7) REX|=2; disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_U1s=4; disp_abs_cnt=tempa1->absolute_address_cnt; } else { SIB+=((tempa1->reg1&7)<<3)+tempa1->reg2&7; if (tempa1->reg1>7) REX|=2; if (tempa1->reg2>7) REX|=1; if (tempa1->reg2==5 && !tempa1->imm_or_off_present && tempa1->indirect) { ModrM+=0x40; disp_U1s=1; ModrM_complete=TRUE; } } } if (!ModrM_complete) { if (tempa1->imm_or_off_present && tempa1->indirect && tempa1->reg1==16) { ModrM=(ModrM & 0xF8)+5; disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_U1s=4; disp_abs_cnt=tempa1->absolute_address_cnt; if (a->seg_size==64) disp_lit=0; } else { if (tempa1->imm_or_off_present) { disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_abs_cnt=tempa1->absolute_address_cnt; if (!disp_exp && MIN_I1<=disp<=MAX_I1) { ModrM+=0x40; disp_U1s=1; } else if (a->seg_size==16) { ModrM+=0x80; disp_U1s=2; } else { ModrM+=0x80; disp_U1s=4; } } else if (!tempa1->indirect) { has_address_prefix=FALSE; ModrM+=0xC0; } else { if (tempa1->reg1==5) { ModrM+=0x40; disp_U1s=1; } } } } } else if (a1>=ARGT_MOFFS8 && a1<=ARGT_MOFFS64) { disp=tempa1->imm; disp_exp=tempa1->exp; disp_local_hash=tempa1->undef_local; disp_glbl_hash=tempa1->undef_glbl; disp_abs_cnt=tempa1->absolute_address_cnt; if (a->seg_size==16) disp_U1s=2; else disp_U1s=4; has_address_prefix=FALSE; } else if (a2>=ARGT_MOFFS8 && a2<=ARGT_MOFFS64) { disp=tempa2->imm; disp_exp=tempa2->exp; disp_local_hash=tempa2->undef_local; disp_glbl_hash=tempa2->undef_glbl; disp_abs_cnt=tempa2->absolute_address_cnt; if (a->seg_size==16) disp_U1s=2; else disp_U1s=4; has_address_prefix=FALSE; } else if (a1>=ARGT_IMM8 && a1<=ARGT_IMM64 || a1>=ARGT_UIMM8 && a1<=ARGT_UIMM64) { imm=tempa1->imm; imm_exp=tempa1->exp; imm_local_hash=tempa1->undef_local; imm_glbl_hash=tempa1->undef_glbl; imm_abs_cnt=tempa1->absolute_address_cnt; if (a1==ARGT_IMM8 || a1==ARGT_UIMM8) imm_U1s=1; else if (a1==ARGT_IMM16 || a1==ARGT_UIMM16) imm_U1s=2; else if (a1==ARGT_IMM32 || a1==ARGT_UIMM32) imm_U1s=4; else { imm_U1s=8; REX|=8; } } if (a2>=ARGT_IMM8 && a2<=ARGT_IMM64 || a2>=ARGT_UIMM8 && a2<=ARGT_UIMM64) { imm=tempa2->imm; imm_exp=tempa2->exp; imm_local_hash=tempa2->undef_local; imm_glbl_hash=tempa2->undef_glbl; imm_abs_cnt=tempa2->absolute_address_cnt; if (a2==ARGT_IMM8 || a2==ARGT_UIMM8) imm_U1s=1; else if (a2==ARGT_IMM16 || a2==ARGT_UIMM16) imm_U1s=2; else if (a2==ARGT_IMM32 || a2==ARGT_UIMM32) imm_U1s=4; else { imm_U1s=8; REX|=8; } } } U1_cnt=tempi->opcode_cnt+disp_U1s+imm_U1s; if (has_ModrM) U1_cnt++; if (has_SIB) U1_cnt++; if (a->seg_size==64) if (REX&0x40==0x40 && (REX!=0x40 || (tempi->flags&IEF_40_REX))) U1_cnt++; if (U1_cntflags & IEF_DONT_SWITCH_MODES && (has_address_prefix || has_operand_prefix))) { best_U1_cnt=U1_cnt; blast_opcode_U1=last_opcode_U1; btempi=tempi; bhas_ModrM=has_ModrM; bModrM=ModrM; bhas_SIB=has_SIB; bSIB=SIB; bREX=REX; bhas_address_prefix=has_address_prefix; bhas_operand_prefix=has_operand_prefix; bis_default=is_default; bdisp=disp; bdisp_U1s=disp_U1s; bdisp_ip_rel=disp_ip_rel; bdisp_lit=disp_lit; bdisp_abs_cnt=disp_abs_cnt; bimm=imm; bimm_U1s=imm_U1s; bimm_ip_rel=imm_ip_rel; bimm_lit=imm_lit; bimm_abs_cnt=imm_abs_cnt; bdisp_exp=disp_exp; bimm_exp=imm_exp; bdisp_local_hash=disp_local_hash; bdisp_glbl_hash=disp_glbl_hash; bimm_local_hash=imm_local_hash; bimm_glbl_hash=imm_glbl_hash; } } } if (best_U1_cnt<255) { if (bhas_operand_prefix) AsmStoreCodeU1(lx,0x66); //Operand size override if (bhas_address_prefix || a->seg_size==16 && has_SIB) AsmStoreCodeU1(lx,0x67); //Operand size override seg=16; if (argcnt>1 && a->arg2.seg!=16 && !a->arg2.just_seg) seg=a->arg2.seg; else if (argcnt>0 && a->arg1.seg!=16 && !a->arg1.just_seg) seg=a->arg1.seg; if (seg!=16) { if (seg==0) AsmStoreCodeU1(lx,0x26); //ES: else if (seg==1) AsmStoreCodeU1(lx,0x2E); //CS: else if (seg==2) AsmStoreCodeU1(lx,0x36); //SS: else if (seg==3) AsmStoreCodeU1(lx,0x3E); //DS: else if (seg==4) AsmStoreCodeU1(lx,0x64); //FS: else AsmStoreCodeU1(lx,0x65); //GS: } if (a->seg_size==64) if (bREX&0x40==0x40 && (bREX!=0x40 || (btempi->flags&IEF_40_REX))) AsmStoreCodeU1(lx,bREX); for (j=0;jopcode_cnt-1;j++) AsmStoreCodeU1(lx,btempi->opcode[j]); AsmStoreCodeU1(lx,blast_opcode_U1); if (bhas_ModrM) AsmStoreCodeU1(lx,bModrM); if (bhas_SIB) AsmStoreCodeU1(lx,bSIB); if (bdisp_U1s) { bdisp_ip_rel=a->ip+bdisp_U1s+bimm_U1s; if (!AsmStoreNum(lx,a,bdisp,FALSE,bdisp_U1s,1,bdisp_ip_rel,bdisp_lit, bdisp_exp,bdisp_local_hash,bdisp_glbl_hash,U1_avail,bdisp_abs_cnt)) return FALSE; } if (bimm_U1s) { bimm_ip_rel=a->ip+bimm_U1s; if (!AsmStoreNum(lx,a,bimm,FALSE,bimm_U1s,1,bimm_ip_rel,bimm_lit, bimm_exp,bimm_local_hash,bimm_glbl_hash,U1_avail,bimm_abs_cnt)) return FALSE; } return TRUE; } // LexPop(lx); PutAsmError(lx,"ST_INVALID_INSTRUCTION"); return FALSE; } void DefineU1s(LexStruct *lx,AsmCtrlStruct *a,I8 num_U1s) { BoolU4 is_question,is_dup; I8 i,dup_value; void *exp; I1 *ptr; LexUndefEntry *undef_locals,*undef_glbls; while (lx->token && lx->token!=';') { undef_locals=NULL; undef_glbls=NULL; if (lx->token==TK_STR) { ptr=lx->ident; i=lx->ident_len-1; while (i--) AsmStoreCodeU1(lx,*ptr++); Lex(lx); //SKip STR } else { is_question=FALSE; is_dup=FALSE; lx->absolute_address_cnt=0; if (lx->token=='?') { is_question=TRUE; Lex(lx); } else { lx->undef_hash_entry=NULL; lx->flags=lx->flags & ~(LF_UNRESOLVED_LOCAL+LF_UNRESOLVED_GLBL); if (!GetExpression(lx,&exp)) LexSkipEol(lx); else { if (lx->flags & (LF_UNRESOLVED_LOCAL | LF_UNRESOLVED_GLBL)) { if (lx->flags & LF_UNRESOLVED_LOCAL) { undef_locals=lx->undef_hash_entry; lx->undef_hash_entry=NULL; a->has_locals=TRUE; } else if (lx->flags & LF_UNRESOLVED_GLBL) { undef_glbls=lx->undef_hash_entry; lx->undef_hash_entry=NULL; } } else { i=Call(exp); DelExpression(exp); } } } if (lx->token==TK_IDENT && lx->hash_entry) { if (lx->hash_entry->type & HTT_KEYWORD && lx->hash_entry->user_data0==AKW_DUP) { if (is_question) PutAsmError(lx,"ST_QUESTION_NOT_ALLOWED"); else { is_dup=TRUE; if (Lex(lx)!='(') PutAsmError(lx,"ST_EXPECTING_LEFT_PAREN"); else { if (Lex(lx)=='?') { is_question=TRUE; Lex(lx); //SKIP "?" } else dup_value=AsmEvalExpression(lx); if (lx->token!=')') PutAsmError(lx,"ST_EXPECTING_RIGHT_PAREN"); else Lex(lx); //SKIP ')' } } } } if (is_dup) { if (undef_locals || undef_glbls) PutAsmError(lx,"ST_UNDEFINED_DUP_CNT"); else AsmStoreNum(lx,a,dup_value,is_question,num_U1s,i,0,1,exp,undef_locals,undef_glbls,FALSE,lx->absolute_address_cnt); } else AsmStoreNum(lx,a,i,is_question,num_U1s,1,0,1,exp,undef_locals,undef_glbls,FALSE,lx->absolute_address_cnt); } if (lx->token==',') Lex(lx); } if (lx->token==';') Lex(lx); else PutAsmError(lx,"ST_MISSING_SEMICOLON"); } void CmpParseAsmBlk(LexStruct *lx) { AsmCtrlStruct *a=lx->a; I8 i,j; OpcodeHashEntry *tempo; SysHashEntry *temph; U8 argcnt,saved_ip; BoolU4 is_literal; U1 *file_buf,*b; U8 file_size; U8 old_hash_mask=lx->hash_mask; I1 *next_last_label; ArcCompressStruct *ac; if (!a) PutAsmError(lx,"ST_ASM_NOT_ALLOWED"); a->seg_size=64; lx->flags|=LF_ASM_EXPRESSIONS; lx->hash_mask&=~(HTT_INTERNAL_TYPE|HTT_CLASS|HTT_PUBLIC| HTT_WORD|HTT_LOCAL_VAR|HTT_GLBL_VAR|HTT_FUNCTION|HTT_FILE| HTT_MODULE|HTT_PRIVATE|HTT_EXPORT|HTT_IMPORT); if (lx->token=='{') Lex(lx); else PrsExcept(lx,"ST_MISSING_RIGHT_BRACE"); while (lx->token && lx->token!='}') { AsmListLine(lx); if (lx->token==TK_IDENT && lx->hash_entry) { if (lx->hash_entry->type==HTT_KEYWORD) { i=lx->hash_entry->user_data0; Lex(lx); //skip keyword switch (i) { case AKW_IMPORT: case AKW_EXPORT: while (lx->token && lx->token!=';') { if (lx->token=='#') { is_literal=TRUE; Lex(lx); } else is_literal=FALSE; if (lx->token==TK_IDENT) { if (temph=lx->hash_entry) { temph=FindHashEntry(lx->ident,a->glbl_hash,HTT_ALL); if (temph) temph->type=HTT_SYS_SYMBOL+HTT_UNRESOLVED_GLBL; } if (!temph) { temph=MAllocZ(sizeof(SysHashEntry)); temph->str=lx->ident; lx->ident=0; temph->type=HTT_SYS_SYMBOL+HTT_UNRESOLVED_GLBL; temph->use_cnt=0; temph->user_data0=0; temph->user_data1=NULL; SetSourceFileInfo(lx,temph); AddSysHashEntry(temph,a->glbl_hash); } if (i==AKW_IMPORT) temph->type|=HTT_IMPORT; else if (i==AKW_EXPORT) temph->type|=HTT_EXPORT; if (is_literal) temph->type|=HTT_LITERAL; if (Lex(lx)==',') Lex(lx); //skip ',' } else { PutAsmError(lx,"ST_EXPECTING_IDENTIFIER"); break; } } if (lx->token!=';') PutAsmError(lx,"ST_MISSING_SEMICOLON"); else Lex(lx); //skip ';'; break; case AKW_ALIGN: if (lx->token!=TK_INTEGER) PutAsmError(lx,"ST_EXPECTING_INTEGER"); else { i=(a->ip+lx->cur_i-1) & -lx->cur_i; if (Lex(lx)==',') Lex(lx); if (lx->token==TK_INTEGER) { for (j=a->ip;jcur_i); Lex(lx); } else a->ip=i; } break; case AKW_END: break; //TODO case AKW_DU1: DefineU1s(lx,a,1); break; case AKW_DU2: DefineU1s(lx,a,2); break; case AKW_DU4: DefineU1s(lx,a,4); break; case AKW_DU8: DefineU1s(lx,a,8); break; case AKW_INSERT: if (lx->token!=TK_STR) PutAsmError(lx,"ST_EXPECTING_STR"); else { file_buf=ReadFile(lx->ident,&file_size); if (file_buf) { for (i=0;itoken!=TK_STR) PutAsmError(lx,"ST_EXPECTING_STR"); else { file_buf=ReadFile(lx->ident,&file_size); if (file_buf) { ac=CompressBuf(file_buf,file_size); b=ac; for (i=0;icompressed_size;i++) AsmStoreCodeU1(lx,b[i]); Free(file_buf); Free(ac); } Lex(lx); } break; case AKW_LIST: a->list=TRUE; break; case AKW_NOLIST: a->list=FALSE; break; case AKW_ORG: a->ip=AsmEvalExpression(lx); break; case AKW_STRUC: a->flags|=ACSF_IN_STRUCT; saved_ip=a->ip; a->ip=AsmEvalExpression(lx); break; case AKW_ENDS: a->ip=saved_ip; a->flags&=~ACSF_IN_STRUCT; break; case AKW_USE16: a->seg_size=16; break; case AKW_USE32: a->seg_size=32; break; case AKW_USE64: a->seg_size=64; break; default: PutAsmError(lx,"ST_SYNTAX_ERROR"); break; } } else if (lx->hash_entry->type & HTT_OPCODE) { tempo=lx->hash_entry; Lex(lx); //skip opcode argcnt=0; if (tempo->ins[0].arg1) { argcnt++; ParseAsmArg(lx,a,&a->arg1,a->ip); if (tempo->ins[0].arg2) { argcnt++; if (lx->token!=',') PutAsmError(lx,"ST_EXPECTING_COMMA"); else { Lex(lx); //skip ',' ParseAsmArg(lx,a,&a->arg2,a->ip); } } } AsmCodeInstruction(lx,a,tempo,argcnt); } else if (lx->hash_entry->type & HTT_SYS_SYMBOL) { if (a->flags & ACSF_IN_STRUCT) lx->hash_entry->type|=HTT_LITERAL; else lx->hash_entry->type&=~HTT_LITERAL; if (lx->hash_entry->type & HTT_UNRESOLVED_LOCAL) { lx->hash_entry->type&=~HTT_UNRESOLVED_LOCAL; lx->hash_entry->user_data0=a->ip; if (Lex(lx)!=':') PutAsmError(lx,"ST_EXPECTING_COLON"); else Lex(lx); } else if (lx->hash_entry->type & HTT_UNRESOLVED_GLBL) { if (lx->hash_entry->type & HTT_IMPORT) PutAsmError(lx,"ST_ATTEMPT_DEFINE_IMPORT"); else { lx->hash_entry->type&=~HTT_UNRESOLVED_GLBL; lx->hash_entry->user_data0=a->ip; next_last_label=lx->hash_entry->str; Lex(lx); //Skip ident if (lx->token!=':' && lx->token!=TK_DOUBLE_COLON) PutAsmError(lx,"ST_EXPECTING_COLON"); else { if (lx->token==TK_DOUBLE_COLON) { lx->hash_entry->type|=HTT_EXPORT; ResolveLocals(lx); a->last_label=next_last_label; } if (Lex(lx)=='#') { Lex(lx); lx->hash_entry->type|=HTT_LITERAL | HTT_EXPORT; } } } } else PutAsmError(lx,"ST_REDEFINITION"); } else PutAsmError(lx,"ST_SYNTAX_ERROR"); } else { if (lx->token==TK_IDENT) { temph=MAllocZ(sizeof(SysHashEntry)); temph->str=lx->ident; lx->ident=0; temph->type=HTT_SYS_SYMBOL; if (a->flags & ACSF_IN_STRUCT) temph->type|=HTT_LITERAL; temph->use_cnt=0; SetSourceFileInfo(lx,temph); temph->user_data0=a->ip; temph->user_data1=NULL; Lex(lx); //Skip ident if (lx->token==':' || lx->token==TK_DOUBLE_COLON) { if (temph->str[0]=='@' && temph->str[1]=='@') { AddSysHashEntry(temph,a->local_hash); a->has_locals=TRUE; } else AddSysHashEntry(temph,a->glbl_hash); if (lx->token==TK_DOUBLE_COLON) { temph->type|=HTT_EXPORT; ResolveLocals(lx); a->last_label=temph->str; Lex(lx); } else { if (Lex(lx)=='#') { temph->type|=HTT_EXPORT | HTT_LITERAL; ResolveLocals(lx); a->last_label=temph->str; Lex(lx); } } } else { PutAsmError(lx,"ST_EXPECTING_COLON"); Free(temph->str); Free(temph); } } else PutAsmError(lx,"ST_SYNTAX_ERROR"); } } ResolveLocals(lx); lx->flags&=~LF_ASM_EXPRESSIONS; lx->hash_mask=old_hash_mask; Lex(lx); //Skip "}" }