#define _TOKR_ #include "tok.h" char useasm=FALSE; char asmparam=FALSE; #include "asmnemon.h" void asmtwo1(int basecode); // used for ADD ADC SUB SBB CMP AND OR XOR. void asmregmem(int out1,int out2); // used for LEA LDS LES LFS LGS LSS. void Scanbit(int basecode); void CheckBit(int code); void asmone1(int basecode); // used for INC and DEC. void asmone2(int basecode); // used for NEG NOT MUL IMUL DIV IDIV. void asmshortjump(int shortcode,int nearcode); void lar_lsl(int code); unsigned char tabldeckr(int code); void protectinstr(int code,int code2); void doasmmov(); // do MOV void asmextend(int basecode); // procedure MOVSX and MOVZX void movd(); void movq(); void packMMX(int code,int code1,int code2); void asmshift(int basecode); // used for ROL ROR RCL RCR SHL SAL SHR SAR. void Shxd(int code); void FpuType1(unsigned int addrm); void FpuType2(unsigned int addrm,unsigned int addrm2); void FpuType3(unsigned int opcode,unsigned int addrm); void FpuType4(unsigned int opcode,unsigned int addrm); void FpuType5(unsigned int opcode,unsigned int addrm); void FpuType6(unsigned int opcode,unsigned int addrm); void FpuType7(unsigned int addrm); void FpuType8(unsigned int opcode,unsigned int addrm); void addlocaljump(int callkind); unsigned long SaveNumber(int type,int tok4,char *name); void cmov(int num); void mmxiii(int type); void prefetch(int code, int type); void pextrw(); void pinsrw(); void pshufw(); void xmminstr(int type,int sec,int op1=tk_xmmreg,int op2=tk_xmmreg); void xmm3instr(int type,int sec); void xmm2xmm(int code,int code2=0,int type=tk_xmmreg); void movxmm(int code,int code2,int addc=1); void movxmm2(int code,int code2=0); void movxmm3(int code,int code2=0,int type=tk_xmmreg); void movxmm4(int code,int code2); void shiftxmm(int rm); //rxmm,i8 void DDDW(int faradd); void AADM(int code); extern void shortjumperror(); extern void invalidfarjumpitem(); extern void invalidfarcallitem(); extern void bytedxexpected(); extern void axalexpected(); extern void clornumberexpected(); extern void reg32regexpected(int type); extern void begexpected(int type); extern void regexpected(int type); extern void invalidoperand(int type); extern void mmxregexpected(int type=0); extern void mmxregordwordexpected(int type); extern void mmxormem(int type); extern void reg32orword(int type); extern void xmmregorvarexpected(int type); extern void xmmregexpected(int type); extern void fpustakexpected(int type); extern void fpuvarexpected(int type); void doasm(int nexta) { unsigned char possiblecpu=0,next=1; int htok; ITOK hstok; char *hbuf; SINFO hstr; unsigned int i=0; int razr=r16; unsigned long hnumber; int faradd=0; if(nexta==FALSE){ useasm=TRUE; nexttok(); useasm=FALSE; } if(tok==tk_idasm){ htok=itok.rm; goto sw_asm; } if(tok==tk_ID||tok==tk_id||tok==tk_undefproc){ if(tok2==tk_colon){ //��⪠ if(tok==tk_undefproc)doanyundefproc(); else doid((char)(tok==tk_ID?1:0),tk_void); return; } strupr((char *)string); htok=FastSearch((unsigned char *)asmMnem,ofsmnem,0,(char *)string); sw_asm: asmparam=TRUE; switch(htok){ case a_add: //ADD case a_or: //OR case a_adc: //ADC case a_sbb: //SBB case a_and: //AND case a_sub: //SUB case a_xor: //XOR case a_cmp: //CMP asmtwo1(htok*8); next=0; break; case a_not: //NOT case a_neg: //NEG case a_mul: //MUL case a_div: //DIV case a_idiv: //IDIV asmone2((htok-a_not)*8+16); break; case a_rol: //ROL case a_ror: //ROR case a_rcl: //RCL case a_rcr: //RCR case a_shl: //SHL case a_shr: //SHR case a_sar: //SAR asmshift((htok-a_rol)*8); next=0; break; case a_btc: //BTC case a_btr: //BTR case a_bts: //BTS case a_bt: //BT CheckBit((htok-a_bt)*8); next=0; break; case a_dec: //DEC case a_inc: //INC asmone1((htok-a_inc)*8); break; case a_shrd: //SHRD case a_shld: //SHLD Shxd((htok-a_shld)*8+0xa4); next=0; break; case a_aaa: ClearReg(AX); op(0x37); //AAA break; case a_aad: ClearReg(AX); AADM(0xD5); //AAD break; case a_aam: ClearReg(AX); AADM(0xD4); //AAM break; case a_aas: ClearReg(AX); op(0x3F); //AAS break; case a_adrsiz: op(0x67); possiblecpu=3; break; case a_arpl: //ARPL nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok!=tk_reg)regexpected(2); switch(htok){ case tk_intvar: case tk_wordvar: #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif CheckAllMassiv(hbuf,2,&hstr,&hstok); KillVar(hstok.name); outseg(&hstok,2); op(0x63); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; case tk_reg: ClearReg(hstok.number); op(0x63); op(192+(unsigned int)itok.number*8+hstok.number); break; default: wordvalexpected(); } possiblecpu=2; break; case a_bound: //BOUND asmregmem(0x62,0); possiblecpu=2; break; case a_lea: asmregmem(0x8D,0); //LEA break; case a_lds: //LDS case a_les: //LES asmregmem(htok-a_les+0xC4,0); break; case a_lss: //LSS asmregmem(0xF,0xB2); possiblecpu=3; break; case a_lgs: //LGS case a_lfs: //LFS asmregmem(0xF,htok-a_lfs+0xB4); possiblecpu=3; break; case a_bswap: //BSWAP nexttok(); ClearReg(itok.number); if(tok==tk_reg32||tok==tk_reg){ op66(tok==tk_reg?r16:r32); op(0x0F); op(0xC8+(unsigned int)itok.number); } else preerror("Expecting 32 bit Register for BSWAP"); possiblecpu=4; break; case a_bsf: //BSF case a_bsr: //BSR Scanbit(htok-a_bsf+0xbc); break; case a_call: //CALL nexttok(); htok=0; if(tok==tk_ID||tok==tk_id){ if(stricmp("FAR",(char *)string)==0){ nexttok(); faradd=8; htok=1; } else if(stricmp("NEAR",(char *)string)==0){ nexttok(); htok=1; } } else if(tok==tk_far){ nexttok(); faradd=8; htok=1; } // printf("call %d\n",tok); switch(tok){ case tk_proc: if(faradd==0){ if(itok.segm==DYNAMIC){ itok.segm=DYNAMIC_USED; updatetree(); } int flag=itok.flag; if(itok.segm<NOT_DYNAMIC){ //�������᪠� ��楤�� addacall(itok.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR)); callloc0(); } else callloc(itok.number); } else invalidfarcallitem(); break; case tk_number: asmparam=FALSE; hnumber=doconstdwordmath(); if(faradd==0)callloc(hnumber); else{ op(0x9A); expecting2(tk_colon); unsigned long tempi=doconstdwordmath(); if(am32==FALSE)outword((unsigned int)tempi); else outdword(tempi); outword(hnumber); } next=0; break; /* CALL num */ case tk_postnumber: if(faradd==0){ itok.number=itok.number-outptr-3; op(0xE8); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(am32==FALSE)outword(itok.number); else outdword(itok.number-2); /* op(0xE8); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(am32==FALSE)outword((unsigned int)itok.number); else outdword(itok.number);*/ } else invalidfarcallitem(); break; case tk_reg32: op66(r32); goto callreg; case tk_reg: op66(r16); callreg: if(faradd==0){ op(0xFF); op(0xD0+(unsigned int)itok.number); } /* CALL reg */ else invalidfarcallitem(); break; case tk_ID: case tk_id: if(faradd==0){ tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void); callloc0(); } /* CALL NEAR */ else invalidfarcallitem(); break; case tk_declare: tok=tk_undefproc; updatetree(); case tk_locallabel: case tk_undefproc: if(faradd==0){ addacall((unsigned int)itok.number, (unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?CALL_NEAR:CALL_32))); callloc0(); } /* CALL NEAR */ else invalidfarcallitem(); break; case tk_dwordvar: case tk_longvar: i=2; if(am32==FALSE&&htok==0)faradd=8; case tk_intvar: case tk_wordvar: i+=2; CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,2); op(0xFF); op(0x10+itok.rm+faradd); outaddress(&itok); break; default: preerror("Invalid item for CALL"); break; } #ifdef OPTVARCONST FreeGlobalConst(); #endif clearregstat(); break; case a_cbw: ClearReg(AX); if(am32)op(0x66); op(0x98); //CBW break; case a_cdq: ClearReg(DX); op66(r32); op(0x99); possiblecpu=3; //CDQ break; case a_clc: op(0xF8); //CLC break; case a_cld: op(0xFC); //CLD break; case a_cli: op(0xFA); //CLI break; case a_clts: //CLTS outword(0x060F); possiblecpu=2; break; case a_cmc: op(0xF5); //CMC break; case a_cmpsb: ClearReg(SI); ClearReg(DI); op(0xA6); break; case a_cmpsw: ClearReg(SI); ClearReg(DI); op66(r16); op(0xA7); break; case a_cmpsd: if(ScanTok3()==tk_camma&&tok2==tk_xmmreg){ xmm3instr(0xC2,0xF2); possiblecpu=9; next=0; } else{ ClearReg(SI); ClearReg(DI); op66(r32); op(0xA7); possiblecpu=3; } break; case a_cmpxchg: //CMPXCHG nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); i=r16; ClearReg(AX); switch(htok){ case tk_reg32: i=r32; case tk_reg: ClearReg(hstok.number); switch(tok){ case tk_reg32: if(i==r16)goto erreg; case tk_reg: op66(i); outword(0xB10F); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_longvar: case tk_dwordvar: if(i==r16)goto erreg; case tk_intvar: case tk_wordvar: #ifdef OPTVARCONST ClearVarByNum(&itok); #endif CheckAllMassiv(bufrm,i,&strinf); op66(i); outseg(&itok,3); outword(0xB10F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: erreg: if(i==r16)wordvalexpected(); else dwordvalexpected(); break; } break; case tk_beg: ClearReg(hstok.number); switch(tok){ case tk_beg: outword(0xB00F); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,1,&strinf); outseg(&itok,3); outword(0xB00F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: bytevalexpected(2); break; } break; case tk_charvar: case tk_bytevar: #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif if(tok!=tk_beg)begexpected(2); CheckAllMassiv(hbuf,1,&hstr,&hstok); KillVar(hstok.name); outseg(&hstok,3); outword(0xB00F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; case tk_longvar: case tk_dwordvar: if(tok!=tk_reg32)reg32expected(2); i=r32; goto noint; case tk_intvar: case tk_wordvar: if(tok!=tk_reg)regexpected(2); noint: #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif CheckAllMassiv(hbuf,i,&hstr,&hstok); KillVar(hstok.name); op66(i); outseg(&hstok,3); outword(0xB10F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: varexpected(1); break; } possiblecpu=4; break; case a_cmpxchg8b: //CMPXCHG8B nexttok(); if(tok!=tk_qwordvar)qwordvalexpected(); #ifdef OPTVARCONST ClearVarByNum(&itok); #endif CheckAllMassiv(bufrm,8,&strinf); KillVar(itok.name); outseg(&itok,3); outword(0xc70f); op(itok.rm+8); outaddress(&itok); possiblecpu=5; break; case a_cwd: ClearReg(DX); op66(r16); op(0x99); //CWD break; case a_cwde: ClearReg(AX); if(!am32)op(0x66); op(0x98); possiblecpu=3; break; case a_cpuid: ClearReg(AX); ClearReg(BX); ClearReg(CX); ClearReg(DX); outword(0xa20f); //CPUID possiblecpu=5; break; case a_daa: ClearReg(AX); op(0x27); //DAA break; case a_das: ClearReg(AX); op(0x2F); //DAS break; case a_db: //DB dbgact++; asmparam=FALSE; do{ i=1; nexttok(); CheckIP(); if(tok==tk_number){ hnumber=doconstdwordmath(); if(tok==tk_id&&strcmp((char *)string,"dup")==0){ i=hnumber; nexttok(); CheckMinusNum(); if(tok==tk_number)hnumber=doconstdwordmath(); else numexpected(); } for(;i!=0;i--)op(hnumber); } else if(tok==tk_string){ for(i=0;i<(unsigned int)itok.number;i++)opd(string[i]); switch(itok.flag&3){ case zero_term: if(itok.flag&s_unicod)opd(0); opd(0); break; case dos_term: if(itok.flag&s_unicod)opd(0); opd('$'); break; } nexttok(); } else{ numexpected(); nexttok(); } }while(tok==tk_camma); dbgact--; next=0; break; case a_dd: //DD faradd++; case a_dw: //DW DDDW(faradd); next=0; break; case a_enter: //ENTER ClearReg(BP); op(0xC8); nexttok(); if(tok==tk_number)outword((unsigned int)doconstlongmath()); else{ numexpected(1); nexttok(); } expecting2(tk_camma); if(tok==tk_number)op((int)doconstlongmath()); else{ numexpected(2); nexttok(); } next=0; possiblecpu=2; break; case a_emms: //EMMS outword(0x770f); possiblecpu=6; break; case a_imul: //IMUL nexttok(); if(tok2!=tk_camma){ ClearReg(AX); switch(tok){ case tk_reg32: possiblecpu=3; razr=r32; case tk_reg: ClearReg(DX); op66(razr); op(246+1); op(128+64+40+(unsigned int)itok.number); break; case tk_beg: op(246); op(128+64+40+(unsigned int)itok.number); break; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,1,&strinf); outseg(&itok,2); op(246); op(itok.rm+40); outaddress(&itok); break; case tk_longvar: case tk_dwordvar: CheckAllMassiv(bufrm,4,&strinf); possiblecpu=3; razr=r32; case tk_intvar: case tk_wordvar: CheckAllMassiv(bufrm,2,&strinf); ClearReg(DX); op66(razr); outseg(&itok,2); op(247); op(itok.rm+40); outaddress(&itok); break; default: varexpected(1); break; } } else{ htok=tok; hnumber=itok.number; ClearReg(hnumber); nextexpecting2(tk_camma); possiblecpu=2; if(tok2!=tk_camma){ switch(tok){ case tk_number: switch(htok){ case tk_reg32: possiblecpu=3; razr=r32; case tk_reg: op66(razr); if(short_ok(itok.number,TRUE))i=2; //���⪠� �ଠ op(0x69+i); op(0xc0+(unsigned int)hnumber+(unsigned int)hnumber*8); if(i==2)op(itok.number); else{ if(htok==tk_reg)outword(itok.number); else outdword(itok.number); } break; default: reg32regexpected(1); } break; case tk_reg32: razr=r32; case tk_reg: op66(razr); possiblecpu=3; if(htok!=tok)reg32regexpected(1); outword(0xaf0f); op(0xc0+(unsigned int)itok.number+(unsigned int)hnumber*8); break; case tk_longvar: tok++; case tk_dwordvar: if(htok!=tk_reg32)reg32expected(1); CheckAllMassiv(bufrm,4,&strinf); razr=r32; goto imul1; case tk_intvar: tok++; case tk_wordvar: imul1: possiblecpu=3; if(htok!=tk_reg&&(tok==tk_intvar||tok==tk_wordvar))regexpected(1); CheckAllMassiv(bufrm,2,&strinf); op66(razr); outseg(&itok,3); outword(0xaf0f); op(itok.rm+hnumber*8); outaddress(&itok); break; default: varexpected(2); } } else{ int htok2=tok; hstok=itok; hbuf=bufrm; hstr=strinf; strinf.bufstr=NULL; bufrm=NULL; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(3); switch(htok2){ case tk_reg32: possiblecpu=3; razr=r32; case tk_reg: op66(razr); if(htok!=htok2)reg32regexpected(2); if(short_ok(itok.number,TRUE))i=2; //���⪠� �ଠ op(0x69+i); op(0xc0+(unsigned int)hstok.number+(unsigned int)hnumber*8); if(i==2)op(itok.number); else{ if(htok==tk_reg)outword(itok.number); else outdword(itok.number); } break; case tk_longvar: tok++; case tk_dwordvar: possiblecpu=3; if(htok!=tk_reg32)reg32expected(2); CheckAllMassiv(hbuf,4,&hstr,&hstok); razr=r32; goto imul2; case tk_intvar: tok++; case tk_wordvar: imul2: if(htok!=tk_reg&&(htok2==tk_intvar||htok2==tk_wordvar))regexpected(1); CheckAllMassiv(hbuf,2,&hstr,&hstok); op66(razr); if(short_ok(itok.number,TRUE))i=2; //���⪠� �ଠ outseg(&hstok,2); op(0x69+i); op(hstok.rm+hnumber*8); outaddress(&hstok); if(i==2)op(itok.number); else{ if(htok==tk_reg)outword(itok.number); else outdword(itok.number); } break; default: varexpected(2); } } } break; case a_in: //IN ClearReg(AX); nexttok(); if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){ op66(tok==tk_reg?r16:r32); if(tok==tk_reg32)possiblecpu=3; nexttok(); expecting(tk_camma); if(tok==tk_number){ op(0xE5); asmparam=FALSE; if((hnumber=doconstdwordmath())>255)bytedxexpected(); op(hnumber); next = 0; } else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xED); else bytedxexpected(); } else if(tok==tk_beg&&(unsigned int)itok.number==AL){ nexttok(); expecting(tk_camma); if(tok==tk_number){ op(0xE4); asmparam=FALSE; if((hnumber=doconstdwordmath())>255)bytedxexpected(); op(hnumber); next=0; } else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xEC); else bytedxexpected(); } else axalexpected(); break; case a_insb: //INSB ClearReg(AX); ClearReg(DI); op(0x6C); possiblecpu=2; break; case a_insw: //INSW op66(r16); possiblecpu=2; goto insd; break; case a_insd: //INSD op66(r32); possiblecpu=3; insd: op(0x6D); ClearReg(AX); ClearReg(DI); break; case a_int: //INT clearregstat(); nexttok(); if(tok==tk_number){ asmparam=FALSE; htok=doconstlongmath(); if(htok==3)op(0xCC); else{ op(0xCD); op(htok); } next=0; } else numexpected(); break; case a_into: op(0xCE); //INTO break; case a_invd: //INVD outword(0x080F); possiblecpu=4; break; case a_invlpg: //INVLPG nexttok(); switch(tok){ case tk_longvar: case tk_dwordvar: CheckAllMassiv(bufrm,4,&strinf); goto invlgp; case tk_intvar: case tk_wordvar: CheckAllMassiv(bufrm,2,&strinf); invlgp: outseg(&itok,3); outword(0x010F); op(itok.rm+0x38); outaddress(&itok); break; case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; case tk_number: hnumber=doconstdwordmath(); outword(0x010f); op((am32==FALSE?rm_d16:rm_d32)+0x38); if(postnumflag&f_reloc)AddReloc(); if(htok==tk_undefofs)AddUndefOff(2,hstok.name); if(am32)outdword(hnumber); else outword(hnumber); next=0; break; case tk_postnumber: outword(0x010F); op((am32==FALSE?rm_d16:rm_d32)+0x38); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(am32==FALSE)outword(itok.number); //�뫮 0 outdword(itok.number); break; default: varexpected(0); break; } possiblecpu=4; break; case a_iret: #ifdef OPTVARCONST ClearLVIC(); #endif RestoreStack(); clearregstat(); op66(r16); op(0xCF); //IRET break; case a_iretd: #ifdef OPTVARCONST ClearLVIC(); #endif RestoreStack(); clearregstat(); op66(r32); op(0xCF); //IRETD break; case a_jo: case a_jno: case a_jc: case a_jnc: case a_jz: case a_jnz: case a_jna: case a_ja: case a_js: case a_jns: case a_jp: case a_jnp: case a_jl: case a_jnl: case a_jng: case a_jg: RestoreStack(); asmshortjump((htok-a_jo)+0x70,(htok-a_jo)+0x80); next=0; break; case a_jecxz: //JECXZ RestoreStack(); op67(r32); asmshortjump(0xE3,0); next=0; break; case a_jcxz: //JCXZ RestoreStack(); op67(r16); asmshortjump(0xE3,0); next=0; break; case a_jmp: //JMP RestoreStack(); nexttok(); faradd=0; lastcommand=tk_goto; if(stricmp("FAR",itok.name)==0){ nexttok(); faradd=8; } else if(stricmp("NEAR",itok.name)==0)nexttok(); else if(stricmp("SHORT",itok.name)==0){ // case insensitive nexttok(); next=(unsigned char)GOTO(); break; } next=gotol(faradd); break; case a_lahf: ClearReg(AX); op(0x9F); //LAHF break; case a_lar: //LAR case a_lsl: //LSL lar_lsl(htok-a_lar+2); break; case a_leave: //LEAVE RestoreStack(); op(0xC9); ClearReg(BP); possiblecpu = 2; break; case a_lmsw: protectinstr(1,0x30); //LMSW break; case a_loadall: // LOADALL 80286 only outword(0x050F); possiblecpu=2; break; case a_lodsb: ClearReg(SI); ClearReg(AX); op(0xAC); //LODSB break; case a_lodsw: op66(r16); ClearReg(SI); ClearReg(AX); op(0xAD); //LODSW break; case a_lodsd: op66(r32); ClearReg(SI); ClearReg(AX); op(0xAD); possiblecpu =3; //LODSD break; case a_lock: op(0xF0); //LOCK break; case a_loop: ConstToReg(0,CX,(am32+1)*2); op67(r16); asmshortjump(0xE2,0); next=0; break; case a_loopd: ConstToReg(0,CX,r32); possiblecpu=3; op67(r32); asmshortjump(0xE2,0); next=0; break; case a_loopz: //LOOPE LOOPZ ClearReg(CX); asmshortjump(0xE1,0); next=0; break; case a_loopnz: //LOOPNZ LOOPNE ClearReg(CX); asmshortjump(0xE0,0); next=0; break; case a_ltr: protectinstr(0,0x18); //LTR break; case a_str: protectinstr(0,0x08); //STR break; case a_lgdt: next=tabldeckr(0x10); break; case a_lidt: //LIDT next=tabldeckr(0x18); break; case a_lldt: protectinstr(0,0x10); //LLDT break; case a_mov: doasmmov(); next=0; break; case a_movsb: movsb(); //MOVSB break; case a_movsd: if(ScanTok3()==tk_camma&&(tok2==tk_xmmreg||(tok2>=tk_charvar&&tok2<tk_qwordvar))){ movxmm(0x10,0xf2); possiblecpu=9; } else movsd(); //MOVSD break; case a_movsw: movsw(); //MOVSW break; case a_movzx: case a_movsx: asmextend((htok-a_movzx)*8+0xB6); break; case a_movd: movd(); //MOVD break; case a_movq: movq(); //MOVQ break; case a_nop: op(0x90); //NOP break; case a_opsiz: //OPSIZ OPSIZE op(0x66); possiblecpu=3; break; case a_out: //OUT nexttok(); if(tok==tk_number){ if((hnumber=doconstdwordmath())>255)bytedxexpected(); expecting2(tk_camma); if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){ op66(tok==tk_reg?r16:r32); if(tok==tk_reg32)possiblecpu=3; op(0xE7); op(hnumber); } else if(tok==tk_beg&&(unsigned int)itok.number==AL){ op(0xE6); op(hnumber); } else axalexpected(); } else if(tok==tk_reg&&(unsigned int)itok.number==DX){ nextexpecting2(tk_camma); if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){ op66(tok==tk_reg?r16:r32); if(tok==tk_reg32)possiblecpu=3; op(0xEF); } else if(tok==tk_beg&&(unsigned int)itok.number==AL)op(0xEE); else axalexpected(); } else bytedxexpected(); break; case a_outsb: //OUTSB ClearReg(SI); op(0x6E); possiblecpu=2; break; case a_outsw: //OUTSW ClearReg(SI); op66(r16); op(0x6F); possiblecpu=2; break; case a_outsd: //OUTSD ClearReg(SI); op66(r32); op(0x6F); possiblecpu=3; break; case a_pop: //POP RestoreStack(); do{ possiblecpu=0; asmparam=TRUE; nexttok(); razr=r16; switch(tok){ case tk_reg32: possiblecpu=3; razr=r32; case tk_reg: ClearReg(itok.number); op66(razr); op(0x58+(unsigned int)itok.number); break; case tk_dwordvar: tok--; case tk_longvar: CheckAllMassiv(bufrm,4,&strinf); possiblecpu=3; razr=r32; goto pop; case tk_wordvar: tok--; case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); pop: #ifdef OPTVARCONST ClearVarByNum(&itok); #endif KillVar(itok.name); op66(razr); outseg(&itok,2); op(0x8F); op(itok.rm); outaddress(&itok); break; case tk_seg: if(itok.number!=CS){ PopSeg((unsigned int)itok.number); break; } default: preerror("Invalid operand for POP"); break; } if(cpu<possiblecpu)cpu=possiblecpu; asmparam=FALSE; addESP-=razr==r16?2:4; nexttok(); }while(tok==tk_camma); next=0; break; case a_popa: //POPA razr=r16; possiblecpu=2; goto POPAD; case a_popad: //POPAD razr=r32; possiblecpu=3; POPAD: op66(razr); addESP-=razr==r16?16:32; RestoreStack(); clearregstat(); op(0x61); break; case a_popf: razr=r16; goto POPFD; case a_popfd: //POPFD razr=r32; possiblecpu = 3; POPFD: op66(razr); addESP-=razr==r16?2:4; RestoreStack(); op(0x9D); break; case a_push: //PUSH RestoreStack(); do{ asmparam=TRUE; nexttok(); if((razr=Push())==FALSE)preerror("Invalid operand for PUSH"); asmparam=FALSE; addESP+=razr==r16?2:4; }while(tok==tk_camma); next=0; break; case a_pusha: //PUSHA razr=r16; possiblecpu=2; goto PUSHAD; case a_pushad: //PUSHAD razr=r32; possiblecpu=3; PUSHAD: op66(razr); addESP+=razr==r16?16:32; RestoreStack(); op(0x60); break; case a_pushf: razr=r16; goto PUSHFD; case a_pushfd: //PUSHFD razr=r32; possiblecpu=3; PUSHFD: op66(razr); RestoreStack(); op(0x9C); addESP+=razr==r16?2:4; break; case a_pcmpeqd: case a_pcmpeqw: case a_pcmpeqb: case a_packssdw: //+xmm case a_punpckhdq: case a_punpckhwd: case a_punpckhbw: case a_packuswb: //+xmm case a_pcmpgtd: case a_pcmpgtw: case a_pcmpgtb: case a_packsswb: //+xmm case a_punpckldq: case a_punpcklwd: case a_punpcklbw: mmxiii(htok-a_punpcklbw+0x60); break; case a_pmullw: mmxiii(0xD5); //PMULLW break; case a_pmuludq: mmxiii(0xF4); //PMULUDQ break; case a_psubusb: mmxiii(0xD8); //PSUBUSB break; case a_psubusw: mmxiii(0xD9);//PSUBUSW break; case a_pand: //+xmm mmxiii(0xDB); //PAND break; case a_paddusb: //+xmm mmxiii(0xDC); //PADDUSB break; case a_paddusw: //+xmm mmxiii(0xDD);//PADDUSW break; case a_pandn: //+xmm mmxiii(0xDF);//PANDN break; case a_pause: outword(0x90F3); possiblecpu=9; break; case a_pmulhw: mmxiii(0xE5); //PMULHW break; case a_psubsb: mmxiii(0xE8); //PSUBSB break; case a_psubsw: mmxiii(0xE9);//PSUBSW break; case a_por: mmxiii(0xEB); //POR break; case a_paddsb: //+xmm mmxiii(0xEC); //PADDSB break; case a_paddsw: //+xmm mmxiii(0xED);//PADDSW break; case a_pxor: mmxiii(0xEF); //PXOR break; case a_pmaddwd: mmxiii(0xF5); //PMADDWD break; case a_psubb: mmxiii(0xF8); //PSUBB break; case a_psubw: mmxiii(0xF9);//PSUBW break; case a_psubd: mmxiii(0xFA);//PSUBD break; case a_psubq: mmxiii(0xFB);//PSUBQ possiblecpu=9; break; case a_paddb: //+xmm mmxiii(0xFC); //PADDB break; case a_paddw: //+xmm mmxiii(0xFD);//PADDW break; case a_paddd: //+xmm mmxiii(0xFE);//PADDD break; case a_paddq: //+xmm mmxiii(0xD4);//PADDQ possiblecpu=9; break; case a_psrlw: packMMX(0xD1,0x71,0xd0); //PSRLW next=0; break; case a_psrld: packMMX(0xD2,0x72,0xd0);//PSRLD next=0; break; case a_psrlq: packMMX(0xD3,0x73,0xd0);//PSRLQ next=0; break; case a_psraw: packMMX(0xE1,0x71,0xe0); //PSRAW next=0; break; case a_psrad: packMMX(0xE2,0x72,0xe0);//PSRAD next=0; break; case a_psllw: packMMX(0xF1,0x71,0xf0); //PSLLW next=0; break; case a_pslld: packMMX(0xF2,0x72,0xf0);//PSLLD next=0; break; case a_psllq: packMMX(0xF3,0x73,0xf0);//PSLLQ next=0; break; case a_pslldq: shiftxmm(7); next=0; possiblecpu=9; break; case a_psrldq: shiftxmm(3); next=0; possiblecpu=9; break; case a_rdmsr: ClearReg(AX); ClearReg(DX); outword(0X320F); possiblecpu=5; break; case a_rdtsc: outword(0X310F); possiblecpu=5; break; case a_rep: op(0xF3);//REP REPE REPZ ClearReg(CX); break; case a_repnz: op(0xF2); //REPNE REPNZ ClearReg(CX); break; case a_ret: //RET #ifdef OPTVARCONST ClearLVIC(); #endif RestoreStack(); clearregstat(); next=0; if(tok2==tk_number){ // usedirectiv=TRUE; nexttok(); op(0xC2); asmparam=FALSE; outword((unsigned int)doconstlongmath()); // usedirectiv=FALSE; } else{ op(0xC3); nexttok(); } break; case a_retf: #ifdef OPTVARCONST ClearLVIC(); #endif RestoreStack(); clearregstat(); next=0; if(tok2==tk_number){ nexttok(); op(0xCA); asmparam=FALSE; outword((unsigned int)doconstlongmath()); } else{ op(0xCB); nexttok(); }//RETF break; case a_rsm: //RSM outword(0Xaa0F); possiblecpu=5; break; case a_sahf: op(0x9E); //SAHF break; case a_scasb: op(0xAE); //SCASB ClearReg(DI); break; case a_scasw: op66(r16); op(0xAF); //SCASW ClearReg(DI); break; case a_scasd: //SCASD op66(r32); op(0xAF); possiblecpu=3; ClearReg(DI); break; case a_smsw: protectinstr(1,0x20); //SMSW break; case a_stc: op(0xF9); //STC break; case a_std: op(0xFD); //STD break; case a_sti: op(0xFB); //STI break; case a_stosb: stosb(); //STOSB break; case a_stosw: stosw(); //STOSW break; case a_stosd: stosd(); //STOSD break; case a_seto: case a_setno: case a_setc: case a_setnc: case a_setz: case a_setnz: case a_setna: case a_seta: case a_sets: case a_setns: case a_setp: case a_setnp: case a_setl: case a_setnl: case a_setng: case a_setg: i=htok-a_seto; nexttok(); switch(tok){ case tk_beg: ClearReg(itok.number%4); op(0xf); op(0x90+i); op(0xc0+(unsigned int)itok.number); break; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,1,&strinf); KillVar(itok.name); outseg(&itok,3); op(0xf); op(0x90+i); op(itok.rm); outaddress(&itok); break; default: bytevalexpected(0); } possiblecpu=3; break; case a_sgdt: next=tabldeckr(0); break; case a_sidt: next=tabldeckr(0x8); break; case a_sldt: protectinstr(0,0); //SLDT break; case a_fwait: //FWAIT case a_wait: fwait();//WAIT break; case a_wbinvd: //WBINVD outword(0x090F); possiblecpu=4; break; case a_wrmsr: //WRMSR outword(0x300F); possiblecpu=5; break; case a_xadd: //XADD nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); switch(htok){ case tk_reg32: razr=r32; case tk_reg: switch(tok){ case tk_reg32: if(razr==r16)goto erxreg; case tk_reg: RegToReg(itok.number,hstok.number,razr); ClearReg(hstok.number); op66(razr); outword(0xC10F); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_longvar: case tk_dwordvar: if(razr==r16)goto erxreg; case tk_intvar: case tk_wordvar: KillVar(hstok.name); /*if(bufrm==0&&strinf.bufstr==NULL)*/AddRegVar(hstok.number,razr,&itok); CheckAllMassiv(bufrm,razr,&strinf); op66(razr); outseg(&itok,3); outword(0xC10F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: erxreg: wordvalexpected(); break; } break; case tk_beg: switch(tok){ case tk_beg: RegToReg(itok.number,hstok.number,r8); ClearReg(hstok.number%4); outword(0xC00F); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_charvar: case tk_bytevar: KillVar(hstok.name); /*if(bufrm==0&&strinf.bufstr==NULL)*/AddRegVar(hstok.number,r8,&itok); CheckAllMassiv(bufrm,1,&strinf); outseg(&itok,3); outword(0xC00F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: bytevalexpected(2); break; } break; case tk_charvar: case tk_bytevar: if(tok!=tk_beg)begexpected(2); CheckAllMassiv(hbuf,1,&hstr,&hstok); ClearReg(itok.number); KillVar(hstok.name); outseg(&hstok,3); outword(0xC00F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; case tk_longvar: case tk_dwordvar: if(tok!=tk_reg32)reg32expected(2); razr=r32; goto nointxadd; case tk_intvar: case tk_wordvar: if(tok!=tk_reg)regexpected(1); nointxadd: CheckAllMassiv(hbuf,razr,&hstr,&hstok); ClearReg(itok.number); KillVar(hstok.name); op66(razr); outseg(&hstok,3); outword(0xC10F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: varexpected(1); break; } possiblecpu=4; break; case a_xchg: //XCHG nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); switch(htok){ case tk_reg32: razr=r32; possiblecpu=3; case tk_reg: switch(tok){ case tk_reg32: if(razr==r16)goto erregx; case tk_reg: op66(razr); RegSwapReg(hstok.number,itok.number,razr); if(hstok.number==AX)op(0x90+(unsigned int)itok.number); else if((unsigned int)itok.number==AX)op(0x90+hstok.number); else{ op(0x87); op(128+64+(unsigned int)itok.number*8+hstok.number); } break; case tk_longvar: case tk_dwordvar: if(razr==r16)goto erregx; case tk_intvar: case tk_wordvar: CheckAllMassiv(bufrm,razr,&strinf); KillVar(itok.name); IDZToReg(itok.name,hstok.number,razr); op66(razr); outseg(&itok,2); op(0x87); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: erregx: wordvalexpected(); break; } break; case tk_beg: switch(tok){ case tk_beg: RegSwapReg(hstok.number,itok.number,r8); op(0x86); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,1,&strinf); KillVar(itok.name); IDZToReg(itok.name,hstok.number,r8); outseg(&itok,2); op(0x86); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: bytevalexpected(2); break; } break; case tk_charvar: case tk_bytevar: if(tok!=tk_beg)begexpected(2); CheckAllMassiv(hbuf,1,&hstr,&hstok); KillVar(hstok.name); IDZToReg(hstok.name,itok.number,r8); outseg(&hstok,2); op(0x86); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; case tk_longvar: case tk_dwordvar: razr=r32; possiblecpu=3; if(tok!=tk_reg32)reg32expected(2); goto nointx; case tk_intvar: case tk_wordvar: if(tok!=tk_reg)regexpected(2); nointx: CheckAllMassiv(hbuf,razr,&hstr,&hstok); KillVar(hstok.name); IDZToReg(hstok.name,itok.number,razr); op66(razr); outseg(&hstok,2); op(0x87); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: varexpected(1); break; } break; case a_xlat: ClearReg(AX); op(0xD7); //XLAT break; case a_hlt: op(0xF4); //HLT break; case a_verr: protectinstr(0,0x20); //VERR break; case a_verw: protectinstr(0,0x28); //VERW break; case a_test: //TEST if(iTest()==FALSE)invalidoperand(0); next=0; break; case a_fcom: //FCOM FpuType1(0x10); break; case a_fcomp: //FCOMP FpuType1(0x18); break; case a_fadd: //FADD FpuType2(0,0); break; case a_fdiv: //FDIV FpuType2(0x38,0x30); break; case a_fdivr: //FDIVR FpuType2(0x30,0x38); break; case a_fmul: //FMUL FpuType2(0x8,0x8); break; case a_fsub: //FSUB FpuType2(0x28,0x20); break; case a_fsubr: //FSUBR FpuType2(0x20,0x28); break; case a_faddp: //FADDP FpuType3(0xDE,0); break; case a_fdivp: //FDIVP FpuType3(0xDE,0x38); break; case a_fdivrp: //FDIVRP FpuType3(0xDE,0x30); break; case a_ffree: //FFREE FpuType3(0xDD,0); break; case a_fmulp: //FMULP FpuType3(0xDE,8); break; case a_fsubp: //FSUBP FpuType3(0xDE,0x28); break; case a_fsubrp: //FSUBRP FpuType3(0xDE,0x20); break; case a_fucom: //FUCOM FpuType3(0xDD,0x20); break; case a_fucomp: //FUCOMP FpuType3(0xDD,0x28); break; case a_fxch: //FXCH FpuType3(0xD9,8); break; case a_fiadd: //FIADD FpuType4(0,0); break; case a_ficom: //FICOM FpuType4(0,0x10); break; case a_ficomp: //FICOMP FpuType4(0,0x18); break; case a_fidiv: //FIDIV FpuType4(0,0x30); break; case a_fidivr: //FIDIVR FpuType4(0,0x38); break; case a_fild: //FILD FpuType4(1,0); break; case a_fimul: //FIMUL FpuType4(0,8); break; case a_fist: //FIST FpuType4(1,0x10); break; case a_fistp: //FISTP FpuType4(1,0x18); break; case a_fisub: //FISUB FpuType4(0,0x20); break; case a_fisubr: //FISUBR FpuType4(0,0x28); break; case a_fld: //FLD FpuType5(0xD9,0); break; case a_fst: //FST FpuType5(0xDD,0x10); break; case a_fstp: //FSTP FpuType5(0xDD,0x18); break; case a_fbld: //FBLD FpuType6(0xDF,0X20); break; case a_fbstp: //FBSTP FpuType6(0xDF,0X30); break; case a_fildq: //FILDQ FpuType6(0xDF,0x28); break; case a_fldenv: //FLDENV ��� ����������� FpuType6(0xD9,0x20); break; case a_frstor: //FRSTOR ��� ����������� FpuType6(0xDD,0x20); break; case a_fsave: //FSAVE ��� ����������� fwait(); case a_fnsave: //FNSAVE ��� ����������� FpuType6(0xDD,0x30); break; case a_fstenv: //FSTENV ��� ����������� fwait(); case a_fnstenv: //FNSTENV ��� ����������� FpuType6(0xD9,0x30); break; case a_fldcw: //FLDCW FpuType7(0x28); break; case a_fstcw: //FSTCW fwait(); case a_fnstcw: //FNSTCW FpuType7(0x38); break; case a_f2xm1: outword(0xf0d9); //F2XM1 possiblecpu=2; break; case a_fabs: outword(0xE1D9); //FABS break; case a_fchs: outword(0xE0D9); //FCHS break; case a_fclex: //FCLEX fwait(); // outword(0xE2DB); // break; case a_fnclex: outword(0xE2DB); //FNCLEX break; case a_fcompp: outword(0xD9DE); //FCOMPP break; case a_fcos: //FCOS outword(0xFFD9); possiblecpu=3; break; case a_fdecstr: outword(0xF6D9); //FDECSTP break; case a_fdisi: fwait(); case a_fndisi: outword(0xE1DB); //FDISI break; case a_feni: fwait(); case a_fneni: outword(0xE0DB); //FENI break; case a_fincstr: outword(0xF7D9); //FINCSTP break; case a_finit: //FINIT fwait(); case a_fninit: outword(0xE3DB); //FNINIT break; case a_fldlg2: outword(0xECD9); //FLDLG2 break; case a_fldln2: outword(0xEDD9); //FLDLN2 break; case a_fldl2e: outword(0xEAD9); //FLDL2E break; case a_fldl2t: outword(0xE9D9); //FLDL2T break; case a_fldpi: outword(0xEBD9); //FLDPI break; case a_fldz: outword(0xEED9); //FLDZ break; case a_fld1: outword(0xE8D9); //FLD1 break; case a_fnop: outword(0xD0D9); //FNOP break; case a_fpatan: outword(0xF3D9); //FPATAN break; case a_fprem: outword(0xF8D9); //FPREM break; case a_fprem1: outword(0xF5D9); //FPREM1 possiblecpu=3; break; case a_fptan: outword(0xF2D9); //FPTAN break; case a_frndint: outword(0xFCD9); //FRNDINT break; case a_fsetpm: fwait(); case a_fnsetpm: outword(0xE4DB); //FSETPM possiblecpu=2; break; case a_fscale: outword(0XFDD9); //FSCALE break; case a_fsin: //FSIN outword(0xFED9); possiblecpu=3; break; case a_fsincos: //FSINCOS outword(0xFBD9); possiblecpu=3; break; case a_fsqrt: outword(0xFAD9); //FSQRT break; case a_fstsw: //FSTSW fwait(); case a_fnstsw: //FNSTSW nexttok(); switch(tok){ case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); KillVar(itok.name); outseg(&itok,2); op(0xDD); op(itok.rm+0x38); outaddress(&itok); break; case tk_reg: if(itok.number==0)outword(0xe0df); else preerror("Use only AX"); ClearReg(AX); break; default: wordvalexpected(); } break; case a_ftst: outword(0xE4D9); //FTST break; case a_fucompp: //FUCOMPP outword(0xE9DA); possiblecpu=3; break; case a_fxam: outword(0xE5D9); //FXAM break; case a_fxtract: outword(0xF4D9); //FXTRACT break; case a_fyl2x: outword(0xF1D9); //FYL2X break; case a_fyl2xp1: outword(0xF9D9); //FYL2XP1 break; case a_ud2: outword(0x0B0F); //UD2 possiblecpu=7; break; case a_sysenter: outword(0x340F); //SYSENTER possiblecpu=7; break; case a_sysexit: outword(0x350F); //SYSEXIT possiblecpu=7; break; case a_rdpmc: outword(0x330F); //RDPMC possiblecpu=7; break; case a_fcmovnu: i+=8; case a_fcmovnbe: i+=8; case a_fcmovne: i+=8; case a_fcmovnb: FpuType8(0xDB,i); break; case a_fcmovu: i+=8; case a_fcmovbe: i+=8; case a_fcmove: i+=8; case a_fcmovb: FpuType8(0xDA,i); break; case a_fcomi: //FCOMI i+=8; case a_fucomi: FpuType8(0xDB,i+0x28); break; case a_fcomip: i+=8; case a_fucomip: FpuType8(0xDF,i+0x28); break; case a_cmovo: case a_cmovno: case a_cmovc: case a_cmovnc: case a_cmovz: case a_cmovnz: case a_cmovna: case a_cmova: case a_cmovs: case a_cmovns: case a_cmovp: case a_cmovnp: case a_cmovl: case a_cmovnl: case a_cmovng: case a_cmovg: cmov(htok-a_cmovo); possiblecpu=7; break; case a_lfence: //LFENCE outword(0xAE0F); op(0xE8); possiblecpu=9; break; case a_mfence: //MFENCE outword(0xAE0F); op(0xF0); possiblecpu=9; break; case a_sfence: //SFENCE outword(0xAE0F); op(0xF8); possiblecpu=8; break; case a_maskmovq: //MASKMOVQ nexttok(); hnumber=itok.number; if(tok!=tk_mmxreg)mmxregexpected(1); nextexpecting2(tk_camma); if(tok!=tk_mmxreg)mmxregexpected(2); outword(0xF70F); op(0xC0+hnumber+itok.number*8); possiblecpu=8; break; case a_movntq: //MOVNTQ movxmm3(0xE7,0,tk_mmxreg); possiblecpu=8; break; case a_pavgb: mmxiii(0xE0); break; case a_pavgw: mmxiii(0xE3); break; case a_pmaxub: mmxiii(0xDE); break; case a_pmaxsw: mmxiii(0xEE); break; case a_pminub: mmxiii(0xDA); break; case a_pminsw: mmxiii(0xEA); break; case a_pmulhuw: mmxiii(0xE4); break; case a_psadbw: mmxiii(0xF6); break; case a_prefetcht0: prefetch(0x18,1); possiblecpu=8; break; case a_prefetcht1: prefetch(0x18,2); possiblecpu=8; break; case a_prefetcht2: prefetch(0x18,3); possiblecpu=8; break; case a_prefetchnta: prefetch(0x18,0); possiblecpu=8; break; case a_pextrw: pextrw(); next=0; break; case a_pinsrw: pinsrw(); next=0; break; case a_pmovmskb: nexttok(); if(tok!=tk_reg32)reg32expected(1); htok=itok.number; ClearReg(htok); nextexpecting2(tk_camma); if(tok==tk_xmmreg){ op(0x66); possiblecpu=9; } else{ possiblecpu=8; if(tok!=tk_mmxreg)mmxregexpected(2); } outword(0xD70F); op(rm_mod11+htok*8+itok.number); break; case a_pshufw: pshufw(); next=0; possiblecpu=8; break; case a_pshufd: xmm3instr(0x70,0x66); possiblecpu=9; next=0; break; case a_pshufhw: xmm3instr(0x70,0xf3); possiblecpu=9; next=0; break; case a_pshuflw: xmm3instr(0x70,0xf2); possiblecpu=9; next=0; break; case a_addpd: xmminstr(0x58,0x66); possiblecpu=9; break; case a_addps: xmminstr(0x58,0); possiblecpu=8; break; case a_addsd: xmminstr(0x58,0xF2); possiblecpu=9; break; case a_addss: xmminstr(0x58,0xF3); possiblecpu=8; break; case a_addsubpd: xmminstr(0xD0,0x66); possiblecpu=9; break; case a_addsubps: xmminstr(0xD0,0xF2); possiblecpu=9; break; case a_andnpd: xmminstr(0x55,0x66); possiblecpu=9; break; case a_andnps: xmminstr(0x55,0); possiblecpu=8; break; case a_andpd: xmminstr(0x54,0x66); possiblecpu=9; break; case a_andps: xmminstr(0x54,0); possiblecpu=8; break; case a_comisd: xmminstr(0x2F,0x66); possiblecpu=9; break; case a_comiss: xmminstr(0x2F,0); possiblecpu=8; break; case a_divps: xmminstr(0x5E,0); possiblecpu=8; break; case a_divsd: xmminstr(0x5E,0xf2); possiblecpu=9; break; case a_divss: xmminstr(0x5E,0xF3); possiblecpu=8; break; case a_haddpd: xmminstr(0x7C,0x66); possiblecpu=9; break; case a_haddps: xmminstr(0x7C,0xF2); possiblecpu=9; break; case a_hsubpd: xmminstr(0x7D,0x66); possiblecpu=9; break; case a_hsubps: xmminstr(0x7D,0xF2); possiblecpu=9; break; case a_maskmovdqu: xmm2xmm(0xf7,0x66); possiblecpu=9; break; case a_maxpd: xmminstr(0x5f,0x66); possiblecpu=9; break; case a_maxps: xmminstr(0x5F,0); possiblecpu=8; break; case a_maxsd: xmminstr(0x5f,0xf2); possiblecpu=9; break; case a_maxss: xmminstr(0x5F,0xF3); possiblecpu=8; break; case a_minpd: xmminstr(0x5d,0x66); possiblecpu=9; break; case a_minps: xmminstr(0x5D,0); possiblecpu=8; break; case a_minsd: xmminstr(0x5d,0xf2); possiblecpu=9; break; case a_minss: xmminstr(0x5D,0xF3); possiblecpu=8; break; case a_mulpd: xmminstr(0x59,0x66); possiblecpu=9; break; case a_mulps: xmminstr(0x59,0); possiblecpu=8; break; case a_mulsd: xmminstr(0x59,0xF2); possiblecpu=9; break; case a_mulss: xmminstr(0x59,0xF3); possiblecpu=8; break; case a_orpd: xmminstr(0x56,0x66); possiblecpu=9; break; case a_orps: xmminstr(0x56,0); possiblecpu=8; break; case a_rcpps: xmminstr(0x53,0); possiblecpu=8; break; case a_rcpss: xmminstr(0x53,0xF3); possiblecpu=8; break; case a_rsqrtps: xmminstr(0x52,0); possiblecpu=8; break; case a_rsqrtss: xmminstr(0x52,0xF3); possiblecpu=8; break; case a_sqrtpd: xmminstr(0x51,0x66); possiblecpu=9; break; case a_sqrtps: xmminstr(0x51,0); possiblecpu=8; break; case a_sqrtsd: xmminstr(0x51,0xf2); possiblecpu=9; break; case a_sqrtss: xmminstr(0x51,0xF3); possiblecpu=8; break; case a_subpd: xmminstr(0x5C,0x66); possiblecpu=9; break; case a_subps: xmminstr(0x5C,0); possiblecpu=8; break; case a_subsd: xmminstr(0x5C,0xF2); possiblecpu=9; break; case a_subss: xmminstr(0x5C,0xF3); possiblecpu=8; break; case a_ucomisd: xmminstr(0x2E,0x66); possiblecpu=9; break; case a_ucomiss: xmminstr(0x2E,0); possiblecpu=8; break; case a_unpckhpd: xmminstr(0x15,0x66); possiblecpu=9; break; case a_unpckhps: xmminstr(0x15,0); possiblecpu=8; break; case a_unpcklpd: xmminstr(0x14,0x66); possiblecpu=9; break; case a_unpcklps: xmminstr(0x14,0); possiblecpu=8; break; case a_xorpd: xmminstr(0x57,0x66); possiblecpu=9; break; case a_xorps: xmminstr(0x57,0); possiblecpu=8; break; case a_cmppd: xmm3instr(0xC2,0x66); possiblecpu=9; next=0; break; case a_cmpeqpd: case a_cmpltpd: case a_cmplepd: case a_cmpunordpd: case a_cmpneqpd: case a_cmpnltpd: case a_cmpnlepd: case a_cmpordpd: xmminstr(0xC2,0x66); possiblecpu=9; op(htok-a_cmpeqpd); break; case a_cmpps: xmm3instr(0xC2,0); possiblecpu=8; next=0; break; case a_cmpeqps: case a_cmpltps: case a_cmpleps: case a_cmpunordps: case a_cmpneqps: case a_cmpnltps: case a_cmpnleps: case a_cmpordps: xmminstr(0xC2,0); possiblecpu=9; op(htok-a_cmpeqps); break; case a_cmpss: xmm3instr(0xC2,0xF3); possiblecpu=8; next=0; break; case a_cmpeqss: case a_cmpltss: case a_cmpless: case a_cmpunordss: case a_cmpneqss: case a_cmpnltss: case a_cmpnless: case a_cmpordss: xmminstr(0xC2,0xF3); possiblecpu=9; op(htok-a_cmpeqss); break; case a_cmpeqsd: case a_cmpltsd: case a_cmplesd: case a_cmpunordsd: case a_cmpneqsd: case a_cmpnltsd: case a_cmpnlesd: case a_cmpordsd: xmminstr(0xC2,0xF2); op(htok-a_cmpeqsd); possiblecpu=9; break; case a_shufpd: xmm3instr(0xC6,0x66); possiblecpu=9; next=0; break; case a_shufps: xmm3instr(0xC6,0); possiblecpu=8; next=0; break; case a_cvtdq2pd: xmminstr(0xE6,0xF3); possiblecpu=9; break; case a_cvtdq2ps: xmminstr(0x5B,0); possiblecpu=9; break; case a_cvtpd2dq: xmminstr(0xE6,0xF2); possiblecpu=9; break; case a_cvtpd2pi: xmminstr(0x2d,0x66,tk_mmxreg,tk_xmmreg); possiblecpu=9; break; case a_cvtpd2ps: xmminstr(0x5a,0x66); possiblecpu=9; break; case a_cvtpi2pd: xmminstr(0x2a,0x66,tk_xmmreg,tk_mmxreg); possiblecpu=9; break; case a_cvtpi2ps: xmminstr(0x2a,0,tk_xmmreg,tk_mmxreg); possiblecpu=8; break; case a_cvtps2dq: xmminstr(0x5b,0x66); possiblecpu=9; break; case a_cvtps2pd: xmminstr(0x5a,0); possiblecpu=9; break; case a_cvtsi2ss: xmminstr(0x2a,0xf3,tk_xmmreg,tk_reg32); possiblecpu=8; break; case a_cvtps2pi: xmminstr(0x2d,0,tk_mmxreg,tk_xmmreg); possiblecpu=9; break; case a_cvtsd2si: xmminstr(0x2d,0xf2,tk_reg32,tk_xmmreg); possiblecpu=9; break; case a_cvtsd2ss: xmminstr(0x5a,0xf2); possiblecpu=9; break; case a_cvtsi2sd: xmminstr(0x2a,0xf2,tk_xmmreg,tk_reg32); possiblecpu=9; break; case a_cvtss2sd: xmminstr(0x5a,0xf3); possiblecpu=9; break; case a_cvtss2si: xmminstr(0x2d,0xf3,tk_reg32,tk_xmmreg); possiblecpu=8; break; case a_cvttpd2pi: xmminstr(0x2c,0x66,tk_mmxreg,tk_xmmreg); possiblecpu=9; break; case a_cvttpd2dq: xmminstr(0xE6,0x66); possiblecpu=9; break; case a_cvttps2dq: xmminstr(0x5B,0xF3); possiblecpu=9; break; case a_cvttps2pi: xmminstr(0x2c,0,tk_mmxreg,tk_xmmreg); possiblecpu=8; break; case a_cvttsd2si: xmminstr(0x2C,0xF2,tk_reg32,tk_xmmreg); possiblecpu=9; break; case a_cvttss2si: xmminstr(0x2C,0xF3,tk_reg32,tk_xmmreg); possiblecpu=8; break; case a_divpd: xmminstr(0x5E,0x66); possiblecpu=9; break; case a_punpckhqdq: xmminstr(0x6D,0x66); possiblecpu=9; break; case a_punpcklqdq: xmminstr(0x6C,0x66); possiblecpu=9; break; case a_fxrstor: prefetch(0xAE,1); possiblecpu=8; break; case a_fxsave: prefetch(0xAE,0); possiblecpu=8; break; case a_ldmxcsr: prefetch(0xAE,2); possiblecpu=8; break; case a_stmxcsr: prefetch(0xAE,3); possiblecpu=8; break; case a_clflush: prefetch(0xAE,7); possiblecpu=9; break; case a_monitor: outword(0x010F); op(0xc8); possiblecpu=9; break; case a_mwait: outword(0x010F); op(0xc9); possiblecpu=9; break; case a_lddqu: movxmm4(0xF0,0xF2); possiblecpu=9; break; case a_movhlps: xmm2xmm(0x12); possiblecpu=8; break; case a_movlhps: xmm2xmm(0x16); possiblecpu=8; break; case a_movmskps: xmm2xmm(0x50,0,tk_reg32); possiblecpu=8; break; case a_movntdq: movxmm3(0xE7,0x66); possiblecpu=9; break; case a_movntpd: movxmm3(0x2B,0x66); possiblecpu=9; break; case a_movntps: movxmm3(0x2b,0); possiblecpu=8; break; case a_movapd: movxmm(0x28,0x66); possiblecpu=9; break; case a_movaps: movxmm(0x28,0); possiblecpu=8; break; case a_movdqa: movxmm(0x6f,0x66,0x10); possiblecpu=9; break; case a_movddup: xmminstr(0x12,0xF2); possiblecpu=9; break; case a_movshdup: xmminstr(0x16,0xF3); possiblecpu=9; break; case a_movsldup: xmminstr(0x12,0xF3); possiblecpu=9; break; case a_movdqu: movxmm(0x6f,0xf3,0x10); possiblecpu=9; break; case a_movdq2q: xmm2xmm(0xd6,0xf2,tk_mmxreg); possiblecpu=9; break; case a_movhpd: movxmm2(0x16,0x66); possiblecpu=9; break; case a_movlpd: movxmm2(0x12,0x66); possiblecpu=9; break; case a_movmskpd: xmm2xmm(0x50,0x66,tk_reg32); possiblecpu=9; break; case a_movnti: //MOVNTI movxmm3(0xC3,0,tk_reg32); possiblecpu=9; break; case a_movq2dq: //MOVQ2DQ nexttok(); hnumber=itok.number; if(tok!=tk_xmmreg)xmmregexpected(1); nextexpecting2(tk_camma); if(tok!=tk_mmxreg)mmxregexpected(2); op(0xF3); outword(0xD60F); op(0xC0+hnumber+itok.number*8); possiblecpu=9; break; case a_movupd: movxmm(0x10,0x66); possiblecpu=9; break; case a_movups: movxmm(0x10,0); possiblecpu=8; break; case a_movss: movxmm(0x10,0xF3); possiblecpu=8; break; case a_movhps: movxmm2(0x16); possiblecpu=8; break; case a_movlps: movxmm2(0x12); possiblecpu=8; break; case -1: codeexpected(); break; default: preerror("sorry, this instruction is not supported"); break; } asmparam=FALSE; if(cpu<possiblecpu)cpu=possiblecpu; if(next)nexttok(); } else if(tok==tk_seg){ switch((unsigned int)itok.number){ case ES: op(0x26); break; case SS: op(0x36); break; case CS: op(0x2E); break; case DS: op(0x3E); break; case FS: op(0x64); if(cpu<3)cpu=3; break; case GS: op(0x65); if(cpu<3)cpu=3; break; default: beep(); break; } nextexpecting2(tk_colon); } else if(tok==tk_locallabel)define_locallabel(); else if(tok==tk_at&&ScanTok3()==tk_colon){ nexttok(); LLabel(); } else codeexpected(); if(tok==tk_semicolon)nexttok(); } void cmov(int num) { int type=r32; int reg; nexttok(); if(tok==tk_reg)type=r16; else if(tok!=tk_reg32)reg32regexpected(1); reg=itok.number; ClearReg(reg); nextexpecting2(tk_camma); op66(type); switch(tok){ case tk_reg: if(type==r32)reg32expected(2); goto regs; case tk_reg32: if(type==r16)regexpected(2); regs: op(0x0F); op(0x40+num); op(0xC0+reg*8+itok.number); break; case tk_wordvar: case tk_intvar: if(type==r32)dwordvalexpected(); CheckAllMassiv(bufrm,2,&strinf); goto dwords; case tk_dwordvar: case tk_longvar: if(type==r16)wordvalexpected(); CheckAllMassiv(bufrm,4,&strinf); dwords: outseg(&itok,3); op(0x0F); op(0x40+num); op(itok.rm+reg*8); outaddress(&itok); break; default: varexpected(2); break; } } #ifdef OPTVARCONST int GetOperand(int code) { switch(code){ case a_inc: //INC case a_add: return tk_plus; case a_or: return tk_or; case a_and: return tk_and; case a_dec: //DEC case a_sub: return tk_minus; case a_xor: return tk_xor; case a_not: return tk_not; case a_neg: return tk_numsign; case a_shl: return tk_ll; case a_shr: return tk_rr; } return tokens; } #endif void asmtwo1(int basecode) // used for ADD ADC SUB SBB CMP AND OR XOR. { unsigned long holdnumber2; int htok,typet=r16; long longholdnumber; char *hbuf; ITOK hstok; unsigned char next=1; SINFO hstr; #ifdef OPTVARCONST int initconst=FALSE; int operand=GetOperand(basecode/8); #endif nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); int i=tok; switch(htok){ case tk_reg: if((basecode/8)!=a_cmp)ClearReg(hstok.number); switch(tok){ case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; goto wnum; case tk_minus: if(tok2!=tk_number){ wordvalexpected(); break; } case tk_number: wnum: asmparam=FALSE; holdnumber2=doconstlongmath(); next=0; op66(r16); if(hstok.number==AX){ op(4+1+basecode); if((postnumflag&f_reloc)!=0)AddReloc(); if(i==tk_undefofs)AddUndefOff(2,hstok.name); outword(holdnumber2); } else{ if((postnumflag&f_reloc)==0&&short_ok(holdnumber2)){ op(128+2+1); op(128+64+hstok.number+basecode); op(holdnumber2); } else{ op(128+1); op(128+64+hstok.number+basecode); if((postnumflag&f_reloc)!=0)AddReloc(); if(i==tk_undefofs)AddUndefOff(2,hstok.name); outword(holdnumber2); } } break; case tk_postnumber: op66(r16); if(hstok.number==AX)op(4+1+basecode); else{ op(128+1); op(128+64+hstok.number+basecode); } (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); outword((unsigned int)itok.number); break; case tk_reg: op66(r16); op(2+1+basecode); op(128+64+(unsigned int)itok.number+hstok.number*8); break; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); op66(r16); outseg(&itok,2); op(2+1+basecode); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: wordvalexpected(); break; } break; case tk_reg32: if((basecode/8)!=a_cmp)ClearReg(hstok.number); switch(tok){ case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; goto dnum; case tk_minus: i=tk_number; if(tok2!=tk_number){ dwordvalexpected(); break; } case tk_number: dnum: op66(r32); asmparam=FALSE; longholdnumber=doconstdwordmath(); next=0; if(i==tk_number&&(postnumflag&f_reloc)==0&&short_ok(longholdnumber,TRUE)){ op(128+2+1); op(128+64+hstok.number+basecode); op((int)longholdnumber); } else{ if(hstok.number==EAX)op(4+1+basecode); else{ op(128+1); op(128+64+hstok.number+basecode); } if((postnumflag&f_reloc)!=0)AddReloc(); if(i==tk_undefofs)AddUndefOff(2,hstok.name); outdword(longholdnumber); } break; case tk_postnumber: op66(r32); if(hstok.number==EAX)op(4+1+basecode); else{ op(128+1); op(128+64+hstok.number+basecode); } (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); outdword(itok.number); break; case tk_reg32: op66(r32); op(2+1+basecode); op(128+64+(unsigned int)itok.number+hstok.number*8); break; case tk_dwordvar: case tk_longvar: CheckAllMassiv(bufrm,4,&strinf); op66(r32); outseg(&itok,2); op(2+1+basecode); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: dwordvalexpected(); break; } if(cpu<3)cpu=3; break; case tk_beg: if((basecode/8)!=a_cmp)ClearReg(hstok.number>3?hstok.number-4:hstok.number); switch(tok){ case tk_minus: if(tok2!=tk_number){ bytevalexpected(2); break; } case tk_number: asmparam=FALSE; holdnumber2=doconstlongmath(); next=0; if(hstok.number==AL)op(4+basecode); else{ op(128); op(128+64+hstok.number+basecode); } op(holdnumber2); break; case tk_beg: op(2+basecode); op(128+64+(unsigned int)itok.number+hstok.number*8); break; case tk_bytevar: case tk_charvar: CheckAllMassiv(bufrm,1,&strinf); outseg(&itok,2); op(2+basecode); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: bytevalexpected(2); break; } break; case tk_dwordvar: case tk_longvar: typet=r32; if(cpu<3)cpu=3; case tk_intvar: case tk_wordvar: if((basecode/8)!=a_cmp)KillVar(hstok.name); CheckAllMassiv(hbuf,typet,&hstr,&hstok); op66(typet); outseg(&hstok,2); switch(tok){ case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; goto vnum; case tk_minus: if(tok2!=tk_number)goto erval; case tk_number: vnum: asmparam=FALSE; holdnumber2=doconstlongmath(); #ifdef OPTVARCONST if(i==tk_number&&(postnumflag&f_reloc)==0){ initconst=UpdVarConst(&hstok,holdnumber2,tk_dword,operand); } #endif next=0; if(i!=tk_undefofs&&(postnumflag&f_reloc)==0&&short_ok(holdnumber2,typet/2-1)){ op(128+2+1); op(hstok.rm+basecode); outaddress(&hstok); op(holdnumber2); } else{ op(128+1); op(hstok.rm+basecode); outaddress(&hstok); if((postnumflag&f_reloc)!=0)AddReloc(); if(i==tk_undefofs)AddUndefOff(2,hstok.name); if(typet==r16)outword(holdnumber2); else outdword(holdnumber2); } break; case tk_postnumber: if(typet==r32)goto erval; op(128+1); op(hstok.rm+basecode); outaddress(&hstok); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(typet==r16)outword(itok.number); else outdword(itok.number); break; case tk_reg32: if(typet==r16)goto erval; case tk_reg: op(1+basecode); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: erval: if(typet==r16)wordvalexpected(); else dwordvalexpected(); break; } #ifdef OPTVARCONST if(initconst==FALSE)ClearVarByNum(&hstok); #endif break; case tk_bytevar: case tk_charvar: if((basecode/8)!=a_cmp)KillVar(hstok.name); CheckAllMassiv(hbuf,1,&hstr,&hstok); switch(tok){ case tk_minus: if(tok2!=tk_number){ bytevalexpected(2); break; } case tk_number: asmparam=FALSE; holdnumber2=doconstlongmath(); #ifdef OPTVARCONST if((postnumflag&f_reloc)==0){ initconst=UpdVarConst(&hstok,holdnumber2,tk_byte,operand); } #endif next=0; outseg(&hstok,2); op(128); op(hstok.rm+basecode); outaddress(&hstok); op(holdnumber2); break; case tk_beg: outseg(&hstok,2); op(basecode); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: bytevalexpected(2); break; } #ifdef OPTVARCONST if(initconst==FALSE)ClearVarByNum(&hstok); #endif break; default: varexpected(1); break; } if(next)nexttok(); } int GOTO() { unsigned char next=1; CheckIP(); #ifdef OPTVARCONST ClearLVIC(); #endif clearregstat(); switch(tok){ case tk_proc: case tk_interruptproc: if(itok.segm!=NOT_DYNAMIC){ idrec *ptr=itok.rec; itok.segm=ptr->recsegm=DYNAMIC_USED; itok.rm=tok=tk_undefofs; //ᬥ饭�� �� �� �����⭮� ��⪨ goto undefproc; } jumploc(itok.number); //�� ��楤��� ��� ࠭��� break; case tk_number: asmparam=FALSE; jumploc(doconstlongmath());//�� ������� ���� next=0; break; case tk_ID: addlocaljump(CALL_SHORT); //��������� �������� ���� outword(0x00EB); // JMP SHORT break; case tk_id: tobedefined(CALL_SHORT,tk_void);//�������� ������� ���� outword(0x00EB); // JMP SHORT break; case tk_declare: tok=tk_undefproc; updatetree(); case tk_locallabel: case tk_undefproc: //��������� ��� undefproc: addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT)); outword(0x00EB); // JMP SHORT break; default: shortjumperror(); break; } return next; } unsigned char gotol(int faradd) { unsigned char next=1; unsigned long hnumber; unsigned int i=0; CheckIP(); #ifdef OPTVARCONST ClearLVIC(); #endif clearregstat(); switch(tok){ case tk_declare: if(tok2!=tk_openbracket){ tok=tk_undefproc; updatetree(); } case tk_locallabel: case tk_undefproc: if(tok2==tk_openbracket){ asmparam=FALSE; if(doanyundefproc(TRUE)==tokens)next=0; break; } if(faradd==0){ addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32))); jumploc0(); } /* JMP num */ else invalidfarjumpitem(); break; case tk_proc: if(tok2==tk_openbracket){ doanyproc(TRUE); break; } if(itok.segm!=NOT_DYNAMIC){ idrec *ptr=itok.rec; itok.segm=ptr->recsegm=DYNAMIC_USED; itok.rm=tok=tk_undefofs; //ᬥ饭�� �� �� �����⭮� ��⪨ if(faradd==0){ addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32))); jumploc0(); break; } /* JMP num */ } case tk_interruptproc: if(faradd==0)jumploc(itok.number); else invalidfarjumpitem(); break; case tk_apiproc: asmparam=FALSE; if(tok2==tk_openbracket){ if(doanyundefproc(TRUE)==tokens)next=0; } else{ if(FastCallApi==TRUE){ outword(0x25ff); AddApiToPost(itok.number); } else{ addacall(itok.number,(unsigned char)CALL_32); jumploc0(); } } break; case tk_minus: if(tok2!=tk_number)goto err; case tk_number: asmparam=FALSE; hnumber=doconstdwordmath(); if(faradd==0)jumploc(hnumber); else{ op(0xEA); expecting2(tk_colon); int htok=tok; char name[IDLENGTH]; if(tok==tk_undefofs){ tok=tk_number; strcpy(name,itok.name); } unsigned long tempi=doconstdwordmath(); if(postnumflag&f_reloc)AddReloc(); if(htok==tk_undefofs)AddUndefOff(2,name); if(am32==FALSE)outword((unsigned int)tempi); else outdword(tempi); outword((unsigned int)hnumber); } next=0; break; /* JMP num */ case tk_postnumber: if(faradd==0){ op(0xE9); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(am32==FALSE)outword((unsigned int)itok.number); else outdword(itok.number); } else invalidfarjumpitem(); break; case tk_reg32: op66(r32); goto jmpreg; case tk_reg: op66(r16); jmpreg: if(faradd==0){ op(0xFF); op(0xE0+(unsigned int)itok.number); } /* JMP reg */ else invalidfarjumpitem(); break; case tk_ID: if(faradd==0){ addlocaljump(am32==FALSE?JMP_NEAR:JMP_32); jumploc0(); } /* JMP num */ else invalidfarjumpitem(); break; case tk_id: if(faradd==0){ tobedefined(am32==FALSE?JMP_NEAR:JMP_32,tk_void); jumploc0(); } /* JMP num */ else invalidfarjumpitem(); break; case tk_dwordvar: case tk_longvar: i=2; case tk_intvar: case tk_wordvar: i+=2; CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,2); op(0xFF); op(0x20+itok.rm+(faradd==0?(i==4&&am32==0?8:0):8)); outaddress(&itok); break; default: err: preerror("Invalid item for JMP"); break; } return next; } void asmregmem(int out1,int out2) // used for LEA LDS LES LFS LGS LSS. { int holdreg; nexttok(); op66(tok==tk_reg?r16:r32); if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1); holdreg=(unsigned int)itok.number; ClearReg(itok.number); nextexpecting2(tk_camma); switch(tok){ case tk_intvar: case tk_wordvar: case tk_charvar: case tk_bytevar: case tk_longvar: case tk_dwordvar: break; default: varexpected(2); } CheckAllMassiv(bufrm,2,&strinf); if(out2==0)outseg(&itok,2); else outseg(&itok,3); op(out1); if(out2!=0)op(out2); op(itok.rm+holdreg*8); outaddress(&itok); } void Scanbit(int basecode) { unsigned long hnumber; int htok,typet=r16; nexttok(); hnumber=itok.number; ClearReg(itok.number); htok=tok; nextexpecting2(tk_camma); switch(htok){ case tk_reg32: typet=r32; if(tok==tk_reg||tok==tk_wordvar||tok==tk_intvar)goto erval; case tk_reg: switch(tok){ case tk_reg32: if(typet==r16)goto erval; case tk_reg: op66(typet); op(0xf); op(basecode); op(0xc0+(unsigned int)itok.number+hnumber*8); break; case tk_dwordvar: case tk_longvar: if(typet==r16)goto erval; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,typet,&strinf); op66(typet); outseg(&itok,3); op(0xf); op(basecode); op(itok.rm+hnumber*8); outaddress(&itok); break; default: erval: if(typet==r16)wordvalexpected(); else dwordvalexpected(); break; } break; default: reg32regexpected(1); } if(cpu<3)cpu=3; } void CheckBit(int code) { unsigned long holdnumber2; int htok; ITOK hstok; unsigned char next=1; char *hbuf; SINFO hstr; nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); switch(htok){ case tk_reg32: case tk_reg: op66(htok==tk_reg?r16:r32); if(code)ClearReg(hstok.number); switch(tok){ case tk_number: asmparam=FALSE; holdnumber2=doconstlongmath(); next=0; outword(0xba0f); op(0xe0+code+hstok.number); op(holdnumber2); break; case tk_reg32: if(tok!=htok){ dwordvalexpected(); break; } case tk_reg: if(tok!=htok)wordvalexpected(); op(0xf); op(0xa3+code); op(0xc0+hstok.number+(unsigned int)itok.number*8); break; default: wordvalexpected(); break; } break; case tk_intvar: case tk_wordvar: CheckAllMassiv(hbuf,2,&hstr,&hstok); if(code)KillVar(hstok.name); op66(r16); switch(tok){ case tk_number: varc: asmparam=FALSE; holdnumber2=doconstlongmath(); next=0; outseg(&hstok,3); outword(0xba0f); op(hstok.rm+code+0x20); outaddress(&hstok); op(holdnumber2); break; case tk_reg: varreg: outseg(&hstok,3); op(0xf); op(0xa3+code); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); break; default: wordvalexpected(); break; } #ifdef OPTVARCONST if(code)ClearVarByNum(&hstok); #endif break; case tk_dwordvar: case tk_longvar: CheckAllMassiv(hbuf,4,&hstr,&hstok); if(code)KillVar(hstok.name); op66(r32); if(tok==tk_number)goto varc; if(tok==tk_reg32)goto varreg; dwordvalexpected(); break; default: varexpected(1); } if(cpu<3)cpu=3; if(next)nexttok(); } void asmone1(int basecode) // used for INC and DEC. { int razr=r16; #ifdef OPTVARCONST int operand=GetOperand(basecode/8+a_inc); #endif nexttok(); switch(tok){ case tk_reg32: if(cpu<3)cpu=3; razr=r32; case tk_reg: ClearReg(itok.number); op66(razr); op(64+basecode+(unsigned int)itok.number); break; case tk_beg: ClearReg(itok.number); op(254); op(128+64+basecode+(unsigned int)itok.number); break; case tk_charvar: case tk_bytevar: #ifdef OPTVARCONST UpdVarConst(&itok,1,tk_byte,operand); #endif CheckAllMassiv(bufrm,1,&strinf); KillVar(itok.name); outseg(&itok,2); op(254); op(itok.rm+basecode); outaddress(&itok); break; case tk_longvar: case tk_dwordvar: CheckAllMassiv(bufrm,4,&strinf); if(cpu<3)cpu=3; razr=r32; goto dec; case tk_intvar: case tk_wordvar: CheckAllMassiv(bufrm,2,&strinf); dec: #ifdef OPTVARCONST UpdVarConst(&itok,1,tk_dword,operand); #endif KillVar(itok.name); op66(razr); outseg(&itok,2); op(255); op(itok.rm+basecode); outaddress(&itok); break; default: varexpected(0); break; } } void asmone2(int basecode) // used for NEG NOT MUL IMUL DIV IDIV. { int razr=r16; #ifdef OPTVARCONST int operand=GetOperand((basecode-16)/8+a_not); #endif nexttok(); switch(tok){ case tk_reg32: if(cpu<3)cpu=3; razr=r32; case tk_reg: ClearReg(itok.number); op66(razr); op(246+1); op(128+64+basecode+(unsigned int)itok.number); break; case tk_beg: ClearReg(itok.number); op(246); op(128+64+basecode+(unsigned int)itok.number); break; razr=r8; case tk_charvar: case tk_bytevar: #ifdef OPTVARCONST UpdVarConst(&itok,0,tk_dword,operand); #endif CheckAllMassiv(bufrm,1,&strinf); KillVar(itok.name); outseg(&itok,2); op(246); op(itok.rm+basecode); outaddress(&itok); razr=r8; break; case tk_longvar: case tk_dwordvar: CheckAllMassiv(bufrm,4,&strinf); if(cpu<3)cpu=3; razr=r32; goto neg; case tk_intvar: case tk_wordvar: CheckAllMassiv(bufrm,2,&strinf); neg: #ifdef OPTVARCONST UpdVarConst(&itok,0,tk_dword,operand); #endif KillVar(itok.name); op66(razr); outseg(&itok,2); op(247); op(itok.rm+basecode); outaddress(&itok); break; default: varexpected(0); break; } if(basecode!=16&&basecode!=24){ ClearReg(AX); if(razr!=r8)ClearReg(DX); } } void asmshortjump(int shortcode,int nearcode) { unsigned char next=1,shortjump=1; unsigned int address; #ifdef OPTVARCONST ClearLVIC(); #endif nexttok(); if(stricmp("FAR",itok.name)==0){ // case insensitive preerror("FAR jump not available for this instruction"); nexttok(); } else if(stricmp("NEAR",itok.name)==0){ // case insensitive shortjump=0; nexttok(); } else if(stricmp("SHORT",itok.name)==0)nexttok(); // case insensitive if(shortjump){ CheckIP(); switch(tok){ case tk_proc: *(unsigned int *)&itok.number-=outptr+2; if(short_ok(itok.number)){ op(shortcode); op((unsigned int)itok.number); } else shortjumptoolarge(); break; case tk_number: asmparam=FALSE; address=doconstdwordmath()-(outptr+2); if(short_ok(address)){ op(shortcode); op(address); } else shortjumptoolarge(); next=0; break; case tk_ID: addlocaljump(CALL_SHORT); op(shortcode); op(0x00); /* JXX SHORT */ break; case tk_id: tobedefined(CALL_SHORT,tk_void); op(shortcode); op(0x00); /* JXX SHORT */ break; case tk_declare: tok=tk_undefproc; updatetree(); case tk_locallabel: case tk_undefproc: addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT)); op(shortcode); op(0x00); /* JXX SHORT */ break; default: shortjumperror(); break; } } else if(nearcode!=0){ unsigned long numlong; asmparam=FALSE; switch(tok){ case tk_proc: op(0xF); op(nearcode); numlong=itok.number-outptr-2; if(am32==FALSE)outword((unsigned int)numlong); else outdword(numlong-2); break; case tk_number: op(0xF); op(nearcode); numlong=doconstdwordmath()-outptr-2; if(am32==FALSE)outword((unsigned int)numlong); else outdword(numlong-2); next=0; break; case tk_undefofs: // ???? 32 ���� ०�� op(0xF); op(nearcode); AddUndefOff(2,itok.name); outword(-(int)(outptr-2)); if(am32!=FALSE)outword(0x0000); break; case tk_postnumber: op(0xF); op(nearcode); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); numlong=itok.number-outptr-2; if(am32==FALSE)outword((unsigned int)numlong); else outdword(numlong-2); break; case tk_ID: op(0xF); // must go before tobedefined() addlocaljump(am32==FALSE?CALL_NEAR:CALL_32); op(nearcode); outword(0x0000); /* JXX NEAR */ if(am32!=FALSE)outword(0x0000); break; case tk_id: op(0xF); // must go before tobedefined() tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void); op(nearcode); outword(0x0000); /* JXX NEAR */ if(am32!=FALSE)outword(0x0000); break; case tk_declare: tok=tk_undefproc; updatetree(); case tk_locallabel: case tk_undefproc: op(0xF); // must go before addacall() addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?CALL_NEAR:CALL_32))); op(nearcode); outword(0x0000); /* JXX NEAR */ if(am32!=FALSE)outword(0x0000); break; default: preerror("Invalid operand for NEAR jump"); break; } if(cpu<3)cpu=3; } else preerror("NEAR jump not available for this instruction"); if(next)nexttok(); } void lar_lsl(int code) { unsigned char possiblecpu=0; int razr=r16; nexttok(); if(tok!=tk_reg&&tok!=tk_reg32)reg32regexpected(1); int htok=tok; int hnumber=(unsigned int)itok.number; ClearReg(itok.number); nextexpecting2(tk_camma); switch(tok){ case tk_reg32: if(htok==tk_reg)reg32expected(1); possiblecpu=3; razr=r32; goto lar; case tk_reg: if(htok==tk_reg32)regexpected(1); possiblecpu=2; lar: op66(razr); op(0x0f); op(code); op(0xc0+(unsigned int)itok.number+hnumber*8); break; case tk_longvar: case tk_dwordvar: if(htok==tk_reg)reg32expected(1); CheckAllMassiv(bufrm,4,&strinf); possiblecpu=3; razr=r32; goto lar1; case tk_intvar: case tk_wordvar: if(htok==tk_reg32)regexpected(1); possiblecpu=2; CheckAllMassiv(bufrm,2,&strinf); lar1: op66(razr); outseg(&itok,3); op(0x0f); op(code); op(itok.rm+hnumber*8); outaddress(&itok); break; default: invalidoperand(2); break; } if(possiblecpu>cpu)cpu=possiblecpu; } unsigned char tabldeckr(int code) { unsigned int i=0; int htok; unsigned char next=1; char name[IDLENGTH]; nexttok(); htok=tok; KillVar(itok.name); switch(tok){ case tk_longvar: case tk_dwordvar: i=2; case tk_intvar: case tk_wordvar: i++; case tk_charvar: case tk_bytevar: i++; CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,3); outword(0x010f); op(itok.rm+code); outaddress(&itok); break; case tk_undefofs: strcpy(name,itok.name); tok=tk_number; case tk_number: i=doconstdwordmath(); outword(0x010f); op((am32==FALSE?rm_d16:rm_d32)+code); if(postnumflag&f_reloc)AddReloc(); if(htok==tk_undefofs)AddUndefOff(2,name); if(am32)outdword(i); else outword(i); next=0; break; default: varexpected(0); } if(cpu<2)cpu=2; return next; } void protectinstr(int code,int code2) { int i=0; nexttok(); switch(tok){ case tk_longvar: case tk_dwordvar: i=2; case tk_intvar: case tk_wordvar: i++; case tk_charvar: case tk_bytevar: i++; #ifdef OPTVARCONST ClearVarByNum(&itok); #endif CheckAllMassiv(bufrm,i,&strinf); KillVar(itok.name); outseg(&itok,3); op(0x0f); op(code); op(itok.rm+code2); outaddress(&itok); break; case tk_reg32: case tk_reg: ClearReg(itok.number); op(0x0f); op(code); op(0xc0+code2+(unsigned int)itok.number); break; default: wordvalexpected(); } if(cpu<2)cpu=2; } void doasmmov() // do MOV { unsigned char next=1,possiblecpu=0; int htok,typet; ITOK hstok; char *hbuf; SINFO hstr; #ifdef OPTVARCONST int initconst=FALSE; #endif nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); typet=r16; int i=tok; switch(htok){ case tk_reg32: possiblecpu=3; typet=r32; case tk_reg: switch(tok){ case tk_debugreg: ClearReg(hstok.number); if(typet==r16)goto erreg; outword(0x210F); op(128+64+(unsigned int)itok.number*8+hstok.number); possiblecpu=4; if((unsigned int)itok.number<=DR3||(unsigned int)itok.number==DR6 ||(unsigned int)itok.number==DR7)possiblecpu=3; break; case tk_controlreg: ClearReg(hstok.number); if(typet==r16)goto erreg; outword(0x200F); op(128+64+(unsigned int)itok.number*8+hstok.number); possiblecpu=4; if((unsigned int)itok.number<=CR3)possiblecpu=3; break; case tk_testreg: ClearReg(hstok.number); if(typet==r16)goto erreg; outword(0x240F); op(128+64+(unsigned int)itok.number*8+hstok.number); possiblecpu=4; if((unsigned int)itok.number==TR6||(unsigned int)itok.number==TR7)possiblecpu=3; break; case tk_reg32: if(typet==r16)goto erreg; case tk_reg: RegToReg(hstok.number,itok.number,typet); op66(typet); op(0x89); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; goto wnum; case tk_minus: if(tok2!=tk_number){ wordvalexpected(); break; } case tk_number: wnum: op66(typet); op(0xB8+hstok.number); ClearReg(hstok.number); asmparam=FALSE; SaveNumber(typet,i,hstok.name); next=0; break; case tk_postnumber: ClearReg(hstok.number); op66(typet); op(0xB8+hstok.number); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(typet==r32)outdword(itok.number); else outword((unsigned int)itok.number); break; case tk_dwordvar: case tk_longvar: if(typet==r16)goto erreg; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,typet,&strinf); IDZToReg(itok.name,hstok.number,typet); op66(typet); if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ outseg(&itok,1); op(0xA1); } else{ outseg(&itok,2); op(0x8B); op(itok.rm+hstok.number*8); } outaddress(&itok); break; case tk_seg: if(typet==r32)goto erreg; IDZToReg(itok.name,hstok.number,typet); op66(r16); op(0x8C); op(128+64+(unsigned int)itok.number*8+hstok.number); if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)possiblecpu=3; break; default: erreg: invalidoperand(2); break; } break; case tk_beg: ClearReg(hstok.number%4); switch(tok){ case tk_beg: op(0x88); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_number: op(0xB0+hstok.number); asmparam=FALSE; op((int)doconstlongmath()); next=0; break; case tk_bytevar: case tk_charvar: CheckAllMassiv(bufrm,1,&strinf); if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){ outseg(&itok,1); op(0xA0); } else{ outseg(&itok,2); op(0x8A); op(itok.rm+hstok.number*8); } outaddress(&itok); break; default: invalidoperand(2); break; } break; case tk_seg: if(hstok.number==CS){ invalidoperand(1); break; } switch(tok){ case tk_reg: op66(r16); op(0x8E); op(128+64+hstok.number*8+(unsigned int)itok.number); if(hstok.number==FS||hstok.number==GS)possiblecpu=3; break; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); op66(r16); outseg(&itok,2); op(0x8E); op(itok.rm+hstok.number*8); outaddress(&itok); if(hstok.number==FS||hstok.number==GS)possiblecpu=3; break; default: invalidoperand(2); break; } break; case tk_dwordvar: case tk_longvar: possiblecpu=3; typet=r32; case tk_wordvar: case tk_intvar: KillVar(itok.name); CheckAllMassiv(hbuf,typet,&hstr,&hstok); op66(typet); switch(tok){ case tk_reg32: if(typet==r16)goto ervar; case tk_reg: /*if((tok==tk_reg||tok==tk_reg32)&&hbuf==NULL&&hstr.bufstr==NULL)*/ AddRegVar(itok.number,typet,&hstok); if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){ outseg(&hstok,1); op(0xA3); outaddress(&hstok); } else{ outseg(&hstok,2); op(0x89); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); } break; case tk_undefofs: strcpy(hstok.name,itok.name); tok=tk_number; goto vnum; case tk_minus: if(tok2!=tk_number){ wordvalexpected(); break; } case tk_number: vnum: outseg(&hstok,2); op(0xC7); op(hstok.rm); outaddress(&hstok); asmparam=FALSE; #ifdef OPTVARCONST unsigned long t; t=SaveNumber(typet,i,hstok.name); if(typet==r16)t&=0xffff; else t&=0xffffffff; if((i==tk_number||i==tk_minus)&&(postnumflag&f_reloc)){ Const2Var(&hstok,t,tk_dword); initconst=TRUE; } #else SaveNumber(typet,i,hstok.name); #endif next=0; break; case tk_postnumber: outseg(&hstok,2); op(0xC7); op(hstok.rm); outaddress(&hstok); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(typet==r16)outword((unsigned int)itok.number); else outdword(itok.number); break; case tk_seg: outseg(&hstok,2); if(typet==r32)goto ervar; op(0x8C); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); if(hstok.number==FS||hstok.number==GS)possiblecpu=3; break; default: ervar: invalidoperand(2); break; } #ifdef OPTVARCONST if(initconst==FALSE)ClearVarByNum(&hstok); #endif break; case tk_charvar: case tk_bytevar: KillVar(itok.name); CheckAllMassiv(hbuf,1,&hstr,&hstok); switch(tok){ case tk_beg: /*if(tok==tk_beg&&hbuf==NULL&&hstr.bufstr==NULL)*/ AddRegVar(itok.number,r8,&hstok); if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){ outseg(&hstok,1); op(0xA2); outaddress(&hstok); } else{ outseg(&hstok,2); op(0x88); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); } break; case tk_number: outseg(&hstok,2); op(0xC6); op(hstok.rm); outaddress(&hstok); asmparam=FALSE; #ifdef OPTVARCONST long t; t=doconstlongmath()&0xff; op(t); if((postnumflag&f_reloc)){ initconst=TRUE; Const2Var(&hstok,t,tk_byte); } #else op((int)doconstlongmath()); #endif next=0; break; default: invalidoperand(2); break; } #ifdef OPTVARCONST if(initconst==FALSE)ClearVarByNum(&hstok); #endif break; case tk_debugreg: if(tok==tk_reg32){ outword(0x230F); op(128+64+hstok.number*8+(unsigned int)itok.number); possiblecpu=4; if(hstok.number<=DR3||hstok.number==DR6||hstok.number==DR7)possiblecpu=3; } else invalidoperand(2); break; case tk_controlreg: if(tok==tk_reg32){ outword(0x220F); op(128+64+hstok.number*8+(unsigned int)itok.number); possiblecpu=4; if(hstok.number<=CR3)possiblecpu=3; } else invalidoperand(2); break; case tk_testreg: if(tok==tk_reg32){ outword(0x260F); op(128+64+hstok.number*8+(unsigned int)itok.number); possiblecpu=4; if(hstok.number==TR6||hstok.number==TR7)possiblecpu=3; } else invalidoperand(2); break; default: invalidoperand(1); break; } asmparam=FALSE; if(possiblecpu>cpu)cpu=possiblecpu; if(next)nexttok(); } void asmextend(int basecode) // procedure MOVSX and MOVZX { int regnum; int razr=r16; nexttok(); if(tok==tk_reg32)razr=r32; if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1); regnum=(unsigned int)itok.number*8; ClearReg(itok.number); nextexpecting2(tk_camma); switch(tok){ case tk_reg: op66(razr); op(0xF); op(basecode|1); op(128+64+regnum+(unsigned int)itok.number); break; case tk_beg: op66(razr); op(0xF); op(basecode); op(128+64+regnum+(unsigned int)itok.number); break; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); op66(razr); outseg(&itok,3); op(0xF); op(basecode|1); op(itok.rm+regnum); outaddress(&itok); break; case tk_bytevar: case tk_charvar: CheckAllMassiv(bufrm,1,&strinf); op66(razr); outseg(&itok,3); op(0xF); op(basecode); op(itok.rm+regnum); outaddress(&itok); break; default: varexpected(2); break; } if(cpu<3)cpu=3; } void movd() { ITOK hstok; int htok; char *hbuf; SINFO hstr; int i=0; nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok==tk_xmmreg)i++; switch(htok){ case tk_reg32: ClearReg(hstok.number); if(tok==tk_mmxreg||i){ //MOVD EAX,MM0 if(i)op(0x66); outword(0x7E0F); op(0xc0+hstok.number+(unsigned int)itok.number*8); } else mmxregexpected(2); break; case tk_dwordvar: case tk_longvar: if(tok==tk_mmxreg||i){ //MOVD mem,MM0 #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif CheckAllMassiv(hbuf,4,&hstr,&hstok); KillVar(hstok.name); outseg(&hstok,i==0?3:4); if(i)op(0x66); outword(0x7E0F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); } else mmxregexpected(2); break; case tk_xmmreg: i++; case tk_mmxreg: switch(tok){ case tk_reg32: //MOVD MM0,EAX if(i)op(0x66); outword(0x6E0F); op(0xc0+hstok.number*8+(unsigned int)itok.number); break; case tk_dwordvar: //MOVD MMO,mem case tk_longvar: CheckAllMassiv(bufrm,4,&strinf); outseg(&itok,i==0?3:4); if(i)op(0x66); outword(0x6E0F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: dwordvalexpected(); } break; default: mmxregordwordexpected(1); } if(cpu<6)cpu=6; if(i&&cpu<9)cpu=9; } void movq() { int htok; ITOK hstok; char *hbuf; SINFO hstr; int i=1,xmm=0; nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok==tk_xmmreg)xmm++; switch(htok){ case tk_qwordvar: case tk_doublevar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: if(tok==tk_mmxreg||xmm){ //MOVQ mem,MM0 #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif KillVar(hstok.name); CheckAllMassiv(hbuf,i,&hstr,&hstok); outseg(&hstok,xmm==0?3:4); if(xmm){ op(0x66); outword(0xD60f); } else outword(0x7F0F); op(hstok.rm+(unsigned int)itok.number*8); outaddress(&hstok); } else mmxregexpected(2); break; case tk_mmxreg: switch(tok){ case tk_mmxreg: //MOVQ MM0,MM1 outword(0x6F0F); op(0xc0+hstok.number*8+(unsigned int)itok.number); break; case tk_qwordvar: case tk_doublevar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,3); outword(0x6F0F); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: mmxregordwordexpected(2); } break; case tk_xmmreg: switch(tok){ case tk_xmmreg: op(0xF3); outword(0x7e0F); op(0xc0+hstok.number*8+(unsigned int)itok.number); break; case tk_qwordvar: case tk_doublevar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,4); op(0xF3); outword(0x7E0F); op(itok.rm+hstok.number*8); outaddress(&itok); xmm++; break; default: xmmregorvarexpected(2); } break; default: mmxregordwordexpected(1); } if(cpu<6)cpu=6; if(xmm&&cpu<9)cpu=9; } void packMMX(int code,int code1,int code2) { unsigned int hnumber; int htok,next=TRUE; int i=1; int xmm=FALSE; nexttok(); hnumber=(unsigned int)itok.number; htok=tok; nextexpecting2(tk_camma); if(htok==tk_xmmreg)xmm=TRUE; else if(htok!=tk_mmxreg)mmxregexpected(1); switch(tok){ case tk_mmxreg: if(xmm)xmmregexpected(2); op(0x0f); op(code); op(0xc0+hnumber*8+(unsigned int)itok.number); break; case tk_xmmreg: if(!xmm)mmxregexpected(2); else op(0x66); op(0x0f); op(code); op(0xc0+hnumber*8+(unsigned int)itok.number); break; case tk_number: if(xmm)op(0x66); op(0x0f); op(code1); op(code2+hnumber); asmparam=FALSE; op((unsigned int)doconstlongmath()); next=FALSE; break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,xmm==FALSE?3:4); if(xmm)op(0x66); op(0x0f); op(code); op(itok.rm+hnumber*8); outaddress(&itok); break; default: mmxregordwordexpected(2); break; } if(cpu<6)cpu=6; if(xmm&&cpu<9)cpu=9; if(next==TRUE)nexttok(); } void asmshift(int basecode) // used for ROL ROR RCL RCR SHL SAL SHR SAR. { int htok,precode; unsigned char holdbyte; int usenumsh=TRUE; ITOK hstok; char *hbuf; char next=1; SINFO hstr; int razr=r16; #ifdef OPTVARCONST int operand=GetOperand(basecode/8+a_rol); #endif nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok==tk_beg&&(unsigned int)itok.number==CL){ precode=0xD2; usenumsh=FALSE; } else if(tok==tk_number){ asmparam=FALSE; holdbyte=(unsigned char)doconstlongmath(); if(holdbyte==1){ precode=0xD0; usenumsh=FALSE; } else /*if(holdbyte!=0)*/{ precode=0xC0; if(cpu<2)cpu=2; } next=0; } else clornumberexpected(); // if(precode!=0){ switch(htok){ case tk_reg32: if(cpu<3)cpu=3; razr=r32; case tk_reg: ClearReg(hstok.number); op66(razr); op(precode+1); op(128+64+basecode+hstok.number); break; case tk_beg: ClearReg(hstok.number); op(precode); op(128+64+basecode+hstok.number); break; case tk_charvar: case tk_bytevar: #ifdef OPTVARCONST if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand); else ClearVarByNum(&hstok); #endif CheckAllMassiv(hbuf,1,&hstr,&hstok); KillVar(hstok.name); outseg(&hstok,2); op(precode); op(hstok.rm+basecode); outaddress(&hstok); break; case tk_dwordvar: case tk_longvar: CheckAllMassiv(hbuf,4,&hstr,&hstok); if(cpu<3)cpu=3; razr=r32; goto rol; case tk_wordvar: case tk_intvar: CheckAllMassiv(hbuf,2,&hstr,&hstok); rol: #ifdef OPTVARCONST if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand); else ClearVarByNum(&hstok); #endif KillVar(hstok.name); op66(razr); outseg(&hstok,2); op(precode+1); op(hstok.rm+basecode); outaddress(&hstok); break; default: varexpected(1); break; } if(usenumsh)op(holdbyte); if(next)nexttok(); } void CheckCl(int code) { op(0xf); if(tok==tk_beg){ if(itok.number==CL)code++; else clornumberexpected(); } else if(tok!=tk_number)clornumberexpected(); op(code); } void Shxd(int code) { unsigned int h2number; int htok,h2tok; ITOK hstok; char *hbuf; unsigned char next=1; SINFO hstr; nexttok(); hstok=itok; htok=tok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); h2number=(unsigned int)itok.number; ClearReg(itok.number); h2tok=tok; nextexpecting2(tk_camma); switch(htok){ case tk_reg: if(h2tok==tk_reg){ op66(r16); regreg: ClearReg(hstok.number); CheckCl(code); op(0xc0+hstok.number+(unsigned int)h2number*8); if(tok==tk_number){ asmparam=FALSE; op(doconstlongmath()); next=0; } } else regexpected(2); break; case tk_reg32: if(h2tok==tk_reg32){ op66(r32); goto regreg; } else reg32expected(2); break; case tk_intvar: case tk_wordvar: if(h2tok==tk_reg){ CheckAllMassiv(hbuf,2,&hstr,&hstok); op66(r16); varreg: #ifdef OPTVARCONST ClearVarByNum(&hstok); #endif KillVar(hstok.name); outseg(&hstok,3); CheckCl(code); op(hstok.rm+h2number*8); outaddress(&hstok); if(tok==tk_number){ asmparam=FALSE; op(doconstlongmath()); next=0; } } else regexpected(2); break; case tk_dwordvar: case tk_longvar: if(h2tok==tk_reg32){ CheckAllMassiv(hbuf,4,&hstr,&hstok); op66(r32); goto varreg; } else reg32expected(2); break; default: valueexpected(); } if(cpu<3)cpu=3; if(next)nexttok(); } void FpuType1(unsigned int addrm) { int opcode=0xd8; int oscan=scanlexmode; scanlexmode=ASMLEX; nexttok(); retoldscanmode(oscan); if(tok==tk_endline||tok==tk_semicolon){ op(0xD8); op(0xC1+addrm); return; } if(tok==tk_double){ opcode=0xdc; nexttok(); } switch(tok){ case tk_fpust: op(0xD8); op(0xC0+(unsigned int)itok.number+addrm); break; case tk_longvar: case tk_dwordvar: case tk_floatvar: CheckAllMassiv(bufrm,4,&strinf); outseg(&itok,2); op(opcode); op(itok.rm+addrm); outaddress(&itok); break; case tk_doublevar: CheckAllMassiv(bufrm,8,&strinf); outseg(&itok,2); op(0xDC); op(itok.rm+addrm); outaddress(&itok); break; default: fpuvarexpected(0); } } void FpuType2(unsigned int addrm,unsigned int addrm2) { long hnum; int opcode=0xd8; int oscan=scanlexmode; scanlexmode=ASMLEX; nexttok(); retoldscanmode(oscan); if(tok==tk_endline||tok==tk_semicolon){ op(0xDE); op(0xC1+addrm); return; } if(tok==tk_double){ opcode=0xdc; nexttok(); } switch(tok){ case tk_fpust: hnum=itok.number; nextexpecting2(tk_camma); if(hnum==0){ if(tok==tk_fpust){ op(0xD8); op(0xC0+addrm2+(unsigned int)itok.number); } else fpustakexpected(2); } else{ if(tok==tk_fpust){ if(itok.number!=0)fpu0expected(); op(0xDC); op(0xC0+(unsigned int)hnum+addrm); } else fpustakexpected(2); } break; case tk_longvar: case tk_dwordvar: case tk_floatvar: CheckAllMassiv(bufrm,4,&strinf); outseg(&itok,2); op(opcode); op(addrm2+itok.rm); outaddress(&itok); break; case tk_doublevar: CheckAllMassiv(bufrm,8,&strinf); outseg(&itok,2); op(0xDC); op(addrm2+itok.rm); outaddress(&itok); break; default: fpuvarexpected(1); } } void FpuType3(unsigned int opcode,unsigned int addrm) { int oscan=scanlexmode; scanlexmode=ASMLEX; nexttok(); // scanlexmode=oscan; retoldscanmode(oscan); if((tok==tk_endline||tok==tk_semicolon)&&opcode!=0xDD){ op(opcode); op(0xC1+addrm); } else if(tok==tk_fpust){ op(opcode); op(0xC0+(unsigned int)itok.number+addrm); } else fpustakexpected(1); if(opcode==0xDE&&tok2==tk_camma){ nexttok(); nexttok(); if(tok!=tk_fpust||itok.number!=0)fpu0expected(); } } void FpuType4(unsigned int opcode,unsigned int addrm) { nexttok(); if(opcode==1&&(addrm==0x18||addrm==0)&&tok==tk_qwordvar){ if(addrm==0)addrm=0x28; else addrm=0x38; CheckAllMassiv(bufrm,8,&strinf); KillVar(itok.name); outseg(&itok,2); op(0xDF); op(itok.rm+addrm); outaddress(&itok); return; } switch(tok){ case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); KillVar(itok.name); outseg(&itok,2); op(0xDE + opcode); op(itok.rm+addrm); outaddress(&itok); break; case tk_longvar: case tk_dwordvar: case tk_floatvar: CheckAllMassiv(bufrm,4,&strinf); KillVar(itok.name); outseg(&itok,2); op(0xDA+opcode); op(itok.rm+addrm); outaddress(&itok); break; default: fpuvarexpected(0); } } void FpuType5(unsigned int opcode,unsigned int addrm) { int opc=0xd9; int i=4; nexttok(); if(tok==tk_qword||tok==tk_double){ nexttok(); tok=tk_qwordvar; } else if((strcmp(itok.name,"tbyte")==0||strcmp(itok.name,"ldouble")==0)&&addrm!=0x10){ opc=0xdb; i=10; if(addrm==0)addrm=40; else addrm=56; nexttok(); if(tok>=tk_charvar&&tok<=tk_wordvar)tok=tk_dwordvar; } switch(tok){ case tk_fpust: op(opcode); op(0xC0+(unsigned int)itok.number+addrm); break; case tk_qwordvar: case tk_doublevar: opc=0xdd; i=8; case tk_longvar: case tk_dwordvar: case tk_floatvar: CheckAllMassiv(bufrm,i,&strinf); if(opcode!=0xD9)KillVar(itok.name); outseg(&itok,2); op(opc); op(itok.rm+addrm); outaddress(&itok); break; default: fpuvarexpected(0); } } void FpuType6(unsigned int opcode,unsigned int addrm) { int i=0; nexttok(); if(opcode==0xDF){ if(tok==tk_qword){ nexttok(); tok=tk_qwordvar; } if(strcmp(itok.name,"tbyte")==0){ i=2; nexttok(); tok=tk_qwordvar; } } switch(tok){ case tk_qwordvar: if(opcode!=0xDF)wordvalexpected(); i=+4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i+=2; CheckAllMassiv(bufrm,i,&strinf); KillVar(itok.name); outseg(&itok,2); op(opcode); op(itok.rm+addrm); outaddress(&itok); break; default: wordvalexpected(); } } void FpuType7(unsigned int addrm) { nexttok(); switch(tok){ case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); if(addrm!=0x28)KillVar(itok.name); outseg(&itok,2); op(0xD9); op(itok.rm+addrm); outaddress(&itok); break; default: wordvalexpected(); } } void FpuType8(unsigned int opcode,unsigned int addrm) { nexttok(); if(tok==tk_fpust&&itok.number==0&&tok2==tk_camma){ nexttok(); nexttok(); } if(tok==tk_fpust){ op(opcode); op(0xC0+(unsigned int)itok.number+addrm); if(cpu<7)cpu=7; } else fpustakexpected(1); } /* ***************** start of some quick codes ****************** */ int short_ok(long thenumber,int reg32) { if(reg32==TRUE){ if(thenumber<=SHORTMAX&&thenumber>=SHORTMIN)return(1); } else{ if((short)thenumber<=SHORTMAX&&(short)thenumber>=SHORTMIN)return(1); } return(0); } void cbw() { if(optimizespeed&&(chip==5||chip==6)){ outdword(0xFCC0C488); //mov ah,al sar AH,7 op(7); } else{ op66(r16); op(0x98); } ClearReg(AX); } void stosb() { op(0xAA); ClearReg(DI); } void stosw() { op66(r16); op(0xAB); ClearReg(DI); } void stosd() { op66(r32); op(0xAB); if(cpu<3)cpu=3; ClearReg(DI); } void movsb() { op(0xA4); ClearReg(DI); ClearReg(SI); } void movsw() { op66(r16); op(0xA5); ClearReg(DI); ClearReg(SI); } void movsd() { op66(r32); op(0xA5); if(cpu<3)cpu=3; ClearReg(DI); ClearReg(SI); } void pushds() /* produce PUSH DS */ { RestoreStack(); op(0x1E); } void pushss() { RestoreStack(); op(0x16); /* PUSH SS */ } void popes() /* produce POP ES */ { RestoreStack(); op(0x07); } void ret() /* produce RET */ { RestoreStack(); op(0xC3); } void retf() /* produce RETF */ { RestoreStack(); op(0xCB); } void jumploc(long loc) /* produce JUMP # */ { loc=loc-outptr-3; if(loc>-130&&loc<127){ loc++; op(0xEB); op(loc); if(loc==0)notunreach=TRUE; } else{ if(am32==FALSE){ op(0xE9); outword(loc); } else{ if(!optimizespeed&&(loc>126&&loc<65533)){ outword(0xE966); outword(loc-1); } else{ op(0xE9); outdword(loc-2); } } } } void callloc(long loc) /* produce CALL # */ { loc=loc-outptr-3; op(0xE8); if(am32==FALSE) outword(loc); else outdword(loc-2); } void xorAHAH() /* produce XOR AH,AH */ { outword(0xE430); ConstToReg(0,AH,r8); } void xorAXAX() /* produce XOR AX,AX */ { op66(r16); outword(0xC031); ConstToReg(0,AX,r16); } void xorEAXEAX() /* produce XOR EAX,EAX */ { op66(r32); outword(0xC031); if(cpu<3)cpu=3; ConstToReg(0,AX,r32); } void ZeroReg(int reg, int razr) { op66(razr); op(0x31); op(0xc0+9*reg); //xor reg,reg ConstToReg(0,reg,razr); } void fwait() { op(0x9B); } void cwdq(int razr) { op66(razr); if(optimizespeed&&(chip==5||chip==6)){ outword(0xC289); //mov dx,ax op66(razr); outword(0xFAC1); //sar dx,15 op(razr==r16?15:31); } else op(0x99); ClearReg(DX); } void nextexpecting2(int want) { nexttok(); expecting2(want); } void expecting2(int want) { if(want!=tok)SwTok(want); nexttok(); } void CheckIP() { if(tok==tk_dollar){ tok=tk_number; itok.number=outptr; } } void jumploc0() { op(0xE9); outword(0); /* the large jump */ if(am32!=FALSE)outword(0); } void callloc0() { op(0xE8); outword(0); if(am32!=FALSE)outword(0); } void Leave() { if((optimizespeed&&chip>3&&chip<7)||chip==0){ outword(0xEC89); // MOV SP,BP op(0x5D); } else op(0xC9); } void tobedefined(int callkind,int expectedreturn) { // strcpy(itok.name,(char *)string); string[0]=0; itok.flag=(unsigned char)(tok==tk_ID?tp_fastcall:(comfile==file_w32?tp_stdcall:tp_pascal)); tok=tk_undefproc; itok.number=secondcallnum; itok.segm=NOT_DYNAMIC; itok.rm=expectedreturn; itok.post=0; addtotree(itok.name); addacall(secondcallnum++,(unsigned char)callkind); } void addlocaljump(int callkind) { addlocalvar((char *)string,tk_locallabel,secondcallnum,TRUE); addacall(secondcallnum++,(char)callkind); } unsigned long SaveNumber(int type,int tok4,char *name) { unsigned long t=doconstdwordmath(); if(tok4==tk_undefofs)AddUndefOff(0,name); else if((postnumflag&f_reloc)!=0)AddReloc(); if(type==r16)outword((unsigned int)t); else outdword(t); return t; } void Swap2tok(int *tok4, ITOK *itok4, char **buf4, SINFO *strinf4, int *tok6, ITOK *itok6, char **buf6, SINFO *strinf6) { int htok; ITOK hstok; char *hbuf; SINFO hstr; htok=*tok4; *tok4=*tok6; *tok6=htok; hstok=*itok4; *itok4=*itok6; *itok6=hstok; hbuf=*buf4; *buf4=*buf6; *buf6=hbuf; hstr=*strinf4; *strinf4=*strinf6; *strinf6=hstr; } int iTest(int mode) { int htok,i; ITOK hstok; char *hbuf; SINFO hstr; unsigned char possiblecpu=0,next=1; unsigned long num; asmparam=TRUE; nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; if(tok==tk_number)hstok.number=doconstlongmath(); else nexttok(); expecting2(tk_camma); i=r16; // printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n", // tok,itok.number,bufrm,htok,hstok.number,hbuf); if(htok==tk_number||htok==tk_postnumber)Swap2tok(&tok,&itok,&bufrm,&strinf, &htok,&hstok,&hbuf,&hstr); // printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n", // tok,itok.number,bufrm,htok,hstok.number,hbuf); switch(htok){ case tk_reg32: i=r32; possiblecpu=3; case tk_reg: switch(tok){ case tk_reg32: if(i==r16){ reg32expected(1); return FALSE; } op66(i); op(0x85); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_reg: if(i==r32){ reg32expected(2); return FALSE; } op66(i); op(0x85); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_number: asmparam=FALSE; num=doconstdwordmath(); if(mode){ if(num<256&&hstok.number<4)goto testal; if(num<65536)i=r16; } op66(i); if(hstok.number==AX)op(0xA9); else{ op(0xF7); op(128+64+hstok.number); } if(i==r16)outword((unsigned int)num); else outdword(num); next=0; break; case tk_postnumber: if(i==r32)return FALSE; op66(r16); if(hstok.number==AX)op(0xA9); else{ op(0xF7); op(128+64+hstok.number); } (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); outword(itok.number); //�뫮 0 break; case tk_dwordvar: case tk_longvar: if(i==r16){ reg32expected(1); return FALSE; } CheckAllMassiv(bufrm,i,&strinf); op66(i); outseg(&itok,2); op(0x85); op(hstok.number*8+itok.rm); outaddress(&itok); break; case tk_wordvar: case tk_intvar: if(i==r32){ regexpected(1); return FALSE; } CheckAllMassiv(bufrm,i,&strinf); op66(i); outseg(&itok,2); op(0x85); op(hstok.number*8+itok.rm); outaddress(&itok); break; default: return FALSE; } break; case tk_beg: switch(tok){ case tk_beg: op(0x84); op(128+64+(unsigned int)itok.number*8+hstok.number); break; case tk_number: asmparam=FALSE; num=doconstdwordmath(); testal: if(hstok.number==AL)op(0xA8); else{ op(0xF6); op(128+64+hstok.number); } op(num); next=0; break; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,1,&strinf); outseg(&itok,2); op(0x84); op(hstok.number*8+itok.rm); outaddress(&itok); break; default: return FALSE; } break; case tk_dwordvar: case tk_longvar: i=r32; possiblecpu=3; case tk_wordvar: case tk_intvar: CheckAllMassiv(hbuf,i,&hstr,&hstok); switch(tok){ case tk_reg32: if(i==r16){ regexpected(2); return FALSE; } op66(i); outseg(&hstok,2); op(0x85); op((unsigned int)itok.number*8+hstok.rm); outaddress(&hstok); break; case tk_reg: if(i==r32){ reg32expected(2); return FALSE; } op66(i); outseg(&hstok,2); op(0x85); op((unsigned int)itok.number*8+hstok.rm); outaddress(&hstok); break; case tk_number: asmparam=FALSE; num=doconstdwordmath(); if(mode){ if(num<256)goto testbyte; if(num<65536)i=r16; } op66(i); outseg(&hstok,2); op(0xF7); op(hstok.rm); outaddress(&hstok); if(i==r32)outdword(num); else outword((unsigned int)num); next=0; break; case tk_postnumber: op66(i); outseg(&hstok,2); if(i==r32)return FALSE; op(0xF7); op(hstok.rm); outaddress(&hstok); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); outword((unsigned int)itok.number); break; default: return FALSE; } break; case tk_charvar: case tk_bytevar: CheckAllMassiv(hbuf,1,&hstr,&hstok); switch(tok){ case tk_beg: outseg(&hstok,2); op(0x84); op((unsigned int)itok.number*8+hstok.rm); outaddress(&hstok); break; case tk_number: asmparam=FALSE; num=doconstdwordmath(); testbyte: outseg(&hstok,2); op(0xF6); op(hstok.rm); outaddress(&hstok); op(num); next=0; break; default: return FALSE; } break; default: return FALSE; } if(cpu<possiblecpu)cpu=possiblecpu; if(next)nexttok(); return TRUE; } void mmxiii(int type) { int num1,i=1; int xmm=FALSE; nexttok(); if(tok==tk_xmmreg)xmm=TRUE; else if(tok!=tk_mmxreg)mmxregexpected(1); num1=itok.number; nextexpecting2(tk_camma); switch(tok){ case tk_mmxreg: if(xmm)xmmregorvarexpected(2); op(0x0F); op(type); op(rm_mod11+itok.number+num1*8); break; case tk_xmmreg: if(xmm==FALSE)mmxormem(2); outword(0x0F66); op(type); op(rm_mod11+itok.number+num1*8); break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,xmm==FALSE?3:4); if(xmm)op(0x66); op(0x0F); op(type); op(itok.rm+num1*8); outaddress(&itok); break; default: mmxormem(2); break; } if(cpu<8)cpu=8; if(xmm&&cpu<9)cpu=9; } void prefetch(int code,int type) { int i=1; nexttok(); switch(tok){ case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); KillVar(itok.name); outseg(&itok,3); op(0x0f); op(code); op(itok.rm+type*8); outaddress(&itok); break; default: datatype_expected(1); break; } } void pextrw() { int num1,num2; int xmm=FALSE; nexttok(); if(tok!=tk_reg32)reg32expected(1); num1=itok.number; ClearReg(num1); nextexpecting2(tk_camma); if(tok==tk_xmmreg)xmm=TRUE; else if(tok!=tk_mmxreg)mmxregexpected(2); num2=itok.number; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(3); if(xmm)op(0x66); outword(0xC50F); op(rm_mod11+num1+num2*8); op(doconstdwordmath()); if(cpu<8)cpu=8; if(xmm&&cpu<9)cpu=9; } void pinsrw() { int num1,htok; ITOK hstok; char *hbuf; SINFO hstr; int xmm=FALSE; nexttok(); if(tok==tk_xmmreg)xmm=TRUE; else if(tok!=tk_mmxreg)mmxregexpected(1); num1=itok.number; nextexpecting2(tk_camma); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(3); switch(htok){ case tk_reg32: if(xmm)op(0x66); outword(0xC40F); op(rm_mod11+num1+hstok.number*8); break; case tk_wordvar: case tk_intvar: CheckAllMassiv(hbuf,2,&hstr); outseg(&hstok,xmm==FALSE?3:4); if(xmm)op(0x66); outword(0xC40F); op(hstok.rm+num1*8); outaddress(&hstok); break; default: reg32orword(2); break; } op(doconstdwordmath()); if(cpu<8)cpu=8; if(xmm&&cpu<9)cpu=9; } void pshufw() { int num1,htok; ITOK hstok; char *hbuf; SINFO hstr; int i=1; nexttok(); if(tok!=tk_mmxreg)mmxregexpected(1); num1=itok.number; nextexpecting2(tk_camma); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(3); switch(htok){ case tk_mmxreg: outword(0x700F); op(rm_mod11+num1+hstok.number*8); break; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(hbuf,i,&hstr); KillVar(hstok.name); outseg(&hstok,3); outword(0x700F); op(hstok.rm+num1*8); outaddress(&hstok); break; default: mmxregordwordexpected(2); break; } op(doconstdwordmath()); } void xmminstr(int type,int sec,int op1,int op2) { int num1,i=1; nexttok(); if(tok!=op1){ if(op1==tk_mmxreg)mmxregexpected(1); else if(op1==tk_reg32)reg32expected(1); else xmmregexpected(1); } if(tok==tk_reg32)ClearReg(itok.number); num1=itok.number; nextexpecting2(tk_camma); switch ( tok ) { case tk_reg32: case tk_mmxreg: case tk_xmmreg: if(tok!=op2){ if(op2==tk_mmxreg)mmxregexpected(2); else if(op2==tk_reg32)reg32expected(2); else xmmregexpected(2); } if(sec)op(sec); op(0x0F); op(type); op(rm_mod11+itok.number+num1*8); break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,sec==0?3:4); if(sec)op(sec); op(0x0F); op(type); op(itok.rm+num1*8); outaddress(&itok); break; default: if(op2==tk_mmxreg)mmxregordwordexpected(2); else if(op2==tk_reg32)reg32orword(2); else xmmregorvarexpected(2); break; } } void xmm3instr(int type,int sec) //xmm,xmm/mem,i8 { int num1,i=1,htok; ITOK hstok; char *hbuf; SINFO hstr; nexttok(); if(tok!=tk_xmmreg)xmmregexpected(1); num1=itok.number; nextexpecting2(tk_camma); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(3); switch(htok){ case tk_xmmreg: if(sec)op(sec); op(0x0F); op(type); op(rm_mod11+hstok.number+num1*8); break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(hbuf,i,&hstr); outseg(&hstok,sec==0?3:4); if(sec)op(sec); op(0x0F); op(type); op(hstok.rm+num1*8); outaddress(&hstok); break; default: xmmregorvarexpected(2); break; } op(doconstdwordmath()); } void xmm2xmm(int code,int code2,int type) { int num; nexttok(); if(tok!=type){ if(type==tk_mmxreg)mmxregexpected(1); else if(type==tk_reg32)reg32expected(1); else xmmregexpected(1); } if(tok==tk_reg32)ClearReg(itok.number); num=itok.number; nextexpecting2(tk_camma); if(tok!=tk_xmmreg)xmmregexpected(2); if(code2)op(code2); op(0x0F); op(code); op(rm_mod11+itok.number+num*8); } void movxmm3(int code,int code2,int type) { int i=1,htok; ITOK hstok; char *hbuf; SINFO hstr; nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); if(tok!=type){ if(type==tk_mmxreg)mmxregexpected(2); else if(type==tk_xmmreg)xmmregexpected(2); else reg32expected(2); } switch(htok){ case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i+=1; case tk_charvar: case tk_bytevar: CheckAllMassiv(hbuf,i,&hstr); KillVar(hstok.name); outseg(&hstok,code2==0?3:4); if(code2)op(code2); op(0x0F); op(code); op(hstok.rm+itok.number*8); outaddress(&hstok); break; default: varexpected(1); } } void movxmm4(int code,int code2) { int i=1; int num; nexttok(); num=itok.number; if(tok!=tk_xmmreg)xmmregexpected(1); nextexpecting2(tk_camma); switch(tok){ case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i+=1; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,(code2==0?3:4)); if(code2)op(code2); op(0x0F); op(code); op(itok.rm+num*8); outaddress(&itok); break; default: varexpected(2); } } void movxmm(int code,int code2,int addc) { int i=1,htok; ITOK hstok; char *hbuf; SINFO hstr; nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); switch(htok){ case tk_xmmreg: switch(tok){ case tk_xmmreg: if(code2)op(code2); op(0x0F); op(code); op(rm_mod11+itok.number+hstok.number*8); break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,(code2==0?3:4)); if(code2)op(code2); op(0x0F); op(code); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: xmmregorvarexpected(2); break; } break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: if(tok!=tk_xmmreg)xmmregexpected(2); CheckAllMassiv(hbuf,i,&hstr); KillVar(hstok.name); outseg(&hstok,code2==0?3:4); if(code2)op(code2); op(0x0F); op(code+addc); op(hstok.rm+itok.number*8); outaddress(&hstok); break; default: xmmregorvarexpected(1); break; } } void movxmm2(int code,int code2) { int i=1,htok; ITOK hstok; char *hbuf; SINFO hstr; nexttok(); htok=tok; hstok=itok; hbuf=bufrm; bufrm=NULL; hstr=strinf; strinf.bufstr=NULL; nextexpecting2(tk_camma); switch(htok){ case tk_xmmreg: switch(tok){ case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: CheckAllMassiv(bufrm,i,&strinf); outseg(&itok,(code2==0?3:4)); if(code2)op(code2); op(0x0F); op(code); op(itok.rm+hstok.number*8); outaddress(&itok); break; default: datatype_expected(2); break; } break; case tk_qwordvar: i+=4; case tk_longvar: case tk_dwordvar: case tk_floatvar: i+=2; case tk_wordvar: case tk_intvar: i++; case tk_charvar: case tk_bytevar: if(tok!=tk_xmmreg)xmmregexpected(2); CheckAllMassiv(hbuf,i,&hstr); KillVar(hstok.name); outseg(&hstok,code2==0?3:4); if(code2)op(code2); op(0x0F); op(code+1); op(hstok.rm+itok.number*8); outaddress(&hstok); break; default: xmmregorvarexpected(1); break; } } void shiftxmm(int rm) //rxmm,i8 { int num; nexttok(); if(tok!=tk_xmmreg)xmmregexpected(1); num=itok.number; nextexpecting2(tk_camma); if(tok!=tk_number)numexpected(2); op(0x66); op(0x0F); op(0x73); op(rm*8+num+rm_mod11); op(doconstdwordmath()); } void DDDW(int faradd) { int htok,i; char name[IDLENGTH]; unsigned long hnumber; if(dbg&2)AddDataNullLine(faradd==0?2:4); dbgact++; asmparam=FALSE; do{ i=1; nexttok(); CheckIP(); htok=tok; switch(tok){ case tk_undefofs: tok=tk_number; strcpy(name,itok.name); case tk_number: hnumber=doconstdwordmath(); if(tok==tk_id&&strcmp((char *)string,"dup")==0){ i=hnumber; nexttok(); CheckMinusNum(); htok=tok; if(tok==tk_undefofs){ tok=tk_number; strcpy(name,itok.name); } if(tok==tk_number)hnumber=doconstdwordmath(); else numexpected(); } for(;i!=0;i--){ if(postnumflag&f_reloc)AddReloc(); if(htok==tk_undefofs)AddUndefOff(2,name); if(faradd)outdword(hnumber); else outword(hnumber); } break; case tk_postnumber: setwordpost(&itok); if(faradd)outdword(itok.number); else outword(itok.number); nexttok(); break; default: numexpected(); nexttok(); break; } }while(tok==tk_camma); dbgact--; } void AADM(int code) { op(code); itok.number=10; if(tok2==tk_number)nexttok(); op(itok.number); //AAD ClearReg(AX); } int Push(ITOK *wtok) { int i; int razr; ITOK hstok; unsigned long hnumber; int possiblecpu=0; int next=1; i=(am32+1)*2; razr=r16; switch(tok){ case tk_id: case tk_ID: if((stricmp("dword",(char *)string)==0)||(stricmp("long",(char *)string)==0))i=r32; else if((stricmp("word",(char *)string)==0)||(stricmp("int",(char *)string)==0))i=r16; else return FALSE; goto swpushpar; case tk_dword: case tk_long: i=r32; goto swpushpar; case tk_int: case tk_word: i=r16; swpushpar: nexttok(); CheckMinusNum(); if(tok==tk_number)goto pushnum; if(tok==tk_undefofs)goto pushundef; return FALSE; case tk_reg32: possiblecpu=3; case tk_reg: op66(tok==tk_reg?r16:r32); op(0x50+(unsigned int)itok.number); break; case tk_seg: PushSeg((unsigned int)itok.number); break; case tk_undefofs: pushundef: hstok=itok; tok=tk_number; hnumber=doconstlongmath(); op66(i); //// op(0x68); if(postnumflag&f_reloc)AddReloc(); AddUndefOff(2,hstok.name); if(i==r16)outword(hnumber); else outdword(hnumber); possiblecpu=(unsigned char)(i==r16?2:3); next=0; break; case tk_minus: if(tok2!=tk_number)return FALSE; case tk_number: pushnum: hnumber=doconstlongmath(); if(i==r16)hnumber&=0xffff; else hnumber&=0xffffffff; if(wtok&&(postnumflag&f_reloc)==0)Const2Var(wtok,hnumber,i==r16?tk_word:tk_dword); op66(i); if((postnumflag&f_reloc)==0&&short_ok(hnumber,i/2-1)){ op(0x6A); op(hnumber); } else{ op(0x68); if((postnumflag&f_reloc)!=0)AddReloc(); if(i==r16)outword(hnumber); else outdword(hnumber); } possiblecpu=(unsigned char)(i==r16?2:3); next=0; break; case tk_dwordvar: case tk_longvar: CheckAllMassiv(bufrm,4,&strinf); possiblecpu=3; razr=r32; goto push; case tk_wordvar: case tk_intvar: CheckAllMassiv(bufrm,2,&strinf); push: op66(razr); outseg(&itok,2); op(0xFF); op(0x30+itok.rm); outaddress(&itok); break; case tk_postnumber: op(0x68); (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); if(am32==FALSE)outword((unsigned int)itok.number); else outdword(itok.number); break; case tk_string: op66(i); op(0x68); if(am32==FALSE)outword(addpoststring()); else outdword(addpoststring()); break; default: return FALSE; } if(cpu<possiblecpu)cpu=possiblecpu; asmparam=FALSE; if(next)nexttok(); return i; } /* end of TOKR.C */