6136 lines
136 KiB
C++
6136 lines
136 KiB
C++
|
#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){ //<2F><>⪠
|
|||
|
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){ //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>᪠<EFBFBD> <20><><EFBFBD>楤<EFBFBD><E6A5A4><EFBFBD>
|
|||
|
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; //<2F><><EFBFBD><EFBFBD>⪠<EFBFBD> <20><>ଠ
|
|||
|
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; //<2F><><EFBFBD><EFBFBD>⪠<EFBFBD> <20><>ଠ
|
|||
|
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; //<2F><><EFBFBD><EFBFBD>⪠<EFBFBD> <20><>ଠ
|
|||
|
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); //<2F>뫮 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 <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
FpuType6(0xD9,0x20);
|
|||
|
break;
|
|||
|
case a_frstor: //FRSTOR <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
FpuType6(0xDD,0x20);
|
|||
|
break;
|
|||
|
case a_fsave: //FSAVE <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
fwait();
|
|||
|
case a_fnsave: //FNSAVE <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
FpuType6(0xDD,0x30);
|
|||
|
break;
|
|||
|
case a_fstenv: //FSTENV <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
fwait();
|
|||
|
case a_fnstenv: //FNSTENV <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
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; //ᬥ饭<E1ACA5><E9A5AD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>⭮<EFBFBD> <20><>⪨
|
|||
|
goto undefproc;
|
|||
|
}
|
|||
|
jumploc(itok.number); //<2F><> <20><><EFBFBD>楤<EFBFBD><E6A5A4><EFBFBD> <20><><EFBFBD> ࠭<><E0A0AD><EFBFBD>
|
|||
|
break;
|
|||
|
case tk_number:
|
|||
|
asmparam=FALSE;
|
|||
|
jumploc(doconstlongmath());//<2F><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
next=0;
|
|||
|
break;
|
|||
|
case tk_ID:
|
|||
|
addlocaljump(CALL_SHORT); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
outword(0x00EB); // JMP SHORT
|
|||
|
break;
|
|||
|
case tk_id:
|
|||
|
tobedefined(CALL_SHORT,tk_void);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFA2AB><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
outword(0x00EB); // JMP SHORT
|
|||
|
break;
|
|||
|
case tk_declare:
|
|||
|
tok=tk_undefproc;
|
|||
|
updatetree();
|
|||
|
case tk_locallabel:
|
|||
|
case tk_undefproc: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA2AB><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
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; //ᬥ饭<E1ACA5><E9A5AD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>⭮<EFBFBD> <20><>⪨
|
|||
|
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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ०<><E0A5A6>
|
|||
|
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); //<2F>뫮 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 */
|
|||
|
|