#define _TOKR_



#include "tok.h"



char useasm=FALSE;

char asmparam=FALSE;

#include "asmnemon.h"



void asmtwo1(int basecode); // used for ADD ADC SUB SBB CMP AND OR XOR.

void asmregmem(int out1,int out2); // used for LEA LDS LES LFS LGS LSS.

void Scanbit(int basecode);

void CheckBit(int code);

void asmone1(int basecode); 			// used for INC and DEC.

void asmone2(int basecode); 			// used for NEG NOT MUL IMUL DIV IDIV.

void asmshortjump(int shortcode,int nearcode);

void lar_lsl(int code);

unsigned char tabldeckr(int code);

void protectinstr(int code,int code2);

void doasmmov();		 // do MOV

void asmextend(int basecode); 	// procedure MOVSX and MOVZX

void movd();

void movq();

void packMMX(int code,int code1,int code2);

void asmshift(int basecode);			// used for ROL ROR RCL RCR SHL SAL SHR SAR.

void Shxd(int code);

void FpuType1(unsigned int addrm);

void FpuType2(unsigned int addrm,unsigned int addrm2);

void FpuType3(unsigned int opcode,unsigned int addrm);

void FpuType4(unsigned int opcode,unsigned int addrm);

void FpuType5(unsigned int opcode,unsigned int addrm);

void FpuType6(unsigned int opcode,unsigned int addrm);

void FpuType7(unsigned int addrm);

void FpuType8(unsigned int opcode,unsigned int addrm);

void addlocaljump(int callkind);

unsigned long SaveNumber(int type,int tok4,char *name);

void cmov(int num);

void mmxiii(int type);

void prefetch(int code, int type);

void pextrw();

void pinsrw();

void pshufw();

void xmminstr(int type,int sec,int op1=tk_xmmreg,int op2=tk_xmmreg);

void xmm3instr(int type,int sec);

void xmm2xmm(int code,int code2=0,int type=tk_xmmreg);

void movxmm(int code,int code2,int addc=1);

void movxmm2(int code,int code2=0);

void movxmm3(int code,int code2=0,int type=tk_xmmreg);

void movxmm4(int code,int code2);

void shiftxmm(int rm);	//rxmm,i8

void DDDW(int faradd);

void AADM(int code);



extern void shortjumperror();

extern void invalidfarjumpitem();

extern void invalidfarcallitem();

extern void bytedxexpected();

extern void axalexpected();

extern void clornumberexpected();

extern void reg32regexpected(int type);

extern void begexpected(int type);

extern void regexpected(int type);

extern void invalidoperand(int type);

extern void mmxregexpected(int type=0);

extern void mmxregordwordexpected(int type);

extern void mmxormem(int type);

extern void reg32orword(int type);

extern void xmmregorvarexpected(int type);

extern void xmmregexpected(int type);

extern void fpustakexpected(int type);

extern void fpuvarexpected(int type);



void doasm(int nexta)

{

unsigned char possiblecpu=0,next=1;

int htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

unsigned int i=0;

int razr=r16;

unsigned long hnumber;

int faradd=0;

	if(nexta==FALSE){

		useasm=TRUE;

		nexttok();

		useasm=FALSE;

	}

	if(tok==tk_idasm){

		htok=itok.rm;

		goto sw_asm;

	}

	if(tok==tk_ID||tok==tk_id||tok==tk_undefproc){

		if(tok2==tk_colon){	//��⪠

			if(tok==tk_undefproc)doanyundefproc();

			else doid((char)(tok==tk_ID?1:0),tk_void);

			return;

		}

		strupr((char *)string);

		htok=FastSearch((unsigned char *)asmMnem,ofsmnem,0,(char *)string);

sw_asm:

		asmparam=TRUE;

		switch(htok){

			case a_add: //ADD

			case a_or:	//OR

			case a_adc: //ADC

			case a_sbb:	//SBB

			case a_and:	//AND

			case a_sub:	//SUB

			case a_xor:	//XOR

			case a_cmp:	//CMP

				asmtwo1(htok*8);

				next=0;

				break;

			case a_not:	//NOT

			case a_neg:	//NEG

			case a_mul:	//MUL

			case a_div:	//DIV

			case a_idiv:	//IDIV

				asmone2((htok-a_not)*8+16);

				break;

			case a_rol:	//ROL

			case a_ror:	//ROR

			case a_rcl:	//RCL

			case a_rcr:	//RCR

			case a_shl:	//SHL

			case a_shr:	//SHR

			case a_sar:	//SAR

				asmshift((htok-a_rol)*8);

				next=0;

				break;

			case a_btc:	//BTC

			case a_btr: //BTR

			case a_bts: //BTS

			case a_bt:	//BT

				CheckBit((htok-a_bt)*8);

				next=0;

				break;

			case a_dec:	//DEC

			case a_inc:	//INC

				asmone1((htok-a_inc)*8);

				break;

			case a_shrd:	//SHRD

			case a_shld:	//SHLD

				Shxd((htok-a_shld)*8+0xa4);

				next=0;

				break;

			case a_aaa:

				ClearReg(AX);

				op(0x37);	//AAA

				break;

			case a_aad:

				ClearReg(AX);

				AADM(0xD5);	//AAD

				break;

			case a_aam:

				ClearReg(AX);

				AADM(0xD4);	//AAM

				break;

			case a_aas:

				ClearReg(AX);

				op(0x3F);	//AAS

				break;

			case a_adrsiz:

				op(0x67);

				possiblecpu=3;

				break;

			case a_arpl:	//ARPL

				nexttok();

				htok=tok;

				hstok=itok;

				hbuf=bufrm;

				bufrm=NULL;

				hstr=strinf;

				strinf.bufstr=NULL;

				nextexpecting2(tk_camma);

				if(tok!=tk_reg)regexpected(2);

				switch(htok){

					case tk_intvar:

					case tk_wordvar:

#ifdef OPTVARCONST

					ClearVarByNum(&hstok);

#endif

						CheckAllMassiv(hbuf,2,&hstr,&hstok);

						KillVar(hstok.name);

						outseg(&hstok,2);

						op(0x63);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					case tk_reg:

						ClearReg(hstok.number);

 						op(0x63);

						op(192+(unsigned int)itok.number*8+hstok.number);

						break;

					default: wordvalexpected();

				}

				possiblecpu=2;

				break;

			case a_bound:	//BOUND

				asmregmem(0x62,0);

				possiblecpu=2;

				break;

			case a_lea:

				asmregmem(0x8D,0);	//LEA

				break;

			case a_lds:	//LDS

			case a_les:	//LES

				asmregmem(htok-a_les+0xC4,0);

				break;

			case a_lss:	//LSS

				asmregmem(0xF,0xB2);

				possiblecpu=3;

				break;

			case a_lgs:	//LGS

			case a_lfs:	//LFS

				asmregmem(0xF,htok-a_lfs+0xB4);

				possiblecpu=3;

				break;

			case a_bswap:	//BSWAP

				nexttok();

				ClearReg(itok.number);

				if(tok==tk_reg32||tok==tk_reg){

					op66(tok==tk_reg?r16:r32);

					op(0x0F);

					op(0xC8+(unsigned int)itok.number);

				}

				else preerror("Expecting 32 bit Register for BSWAP");

				possiblecpu=4;

				break;

			case a_bsf:	//BSF

			case a_bsr:	//BSR

				Scanbit(htok-a_bsf+0xbc);

				break;

			case a_call:	//CALL

				nexttok();

				htok=0;

				if(tok==tk_ID||tok==tk_id){

					if(stricmp("FAR",(char *)string)==0){

						nexttok();

						faradd=8;

						htok=1;

					}

					else if(stricmp("NEAR",(char *)string)==0){

						nexttok();

						htok=1;

					}

				}

				else if(tok==tk_far){

					nexttok();

					faradd=8;

					htok=1;

				}

//				printf("call %d\n",tok);

				switch(tok){

					case tk_proc:

						if(faradd==0){

							if(itok.segm==DYNAMIC){

								itok.segm=DYNAMIC_USED;

								updatetree();

							}

							int flag=itok.flag;

							if(itok.segm<NOT_DYNAMIC){	//�������᪠� ��楤��

								addacall(itok.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));

								callloc0();

							}

							else callloc(itok.number);

						}

						else invalidfarcallitem();

						break;

					case tk_number:

						asmparam=FALSE;

						hnumber=doconstdwordmath();

						if(faradd==0)callloc(hnumber);

						else{

							op(0x9A);

							expecting2(tk_colon);

							unsigned long tempi=doconstdwordmath();

							if(am32==FALSE)outword((unsigned int)tempi);

							else outdword(tempi);

							outword(hnumber);

						}

						next=0;

						break;	 /* CALL num */

					case tk_postnumber:

						if(faradd==0){

							itok.number=itok.number-outptr-3;

							op(0xE8);

							(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

							if(am32==FALSE)outword(itok.number);

							else outdword(itok.number-2);

/*							op(0xE8);

							(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

							if(am32==FALSE)outword((unsigned int)itok.number);

							else outdword(itok.number);*/

						}

						else invalidfarcallitem();

						break;

					case tk_reg32:

						op66(r32);

						goto callreg;

					case tk_reg:

						op66(r16);

callreg:

						if(faradd==0){

							op(0xFF);

							op(0xD0+(unsigned int)itok.number);

						} 	 /* CALL reg */

						else invalidfarcallitem();

						break;

					case tk_ID:

					case tk_id:

						if(faradd==0){

							tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void);

							callloc0();

						} 		 /* CALL NEAR */

						else invalidfarcallitem();

						break;

					case tk_declare:

						tok=tk_undefproc;

						updatetree();

					case tk_locallabel:

					case tk_undefproc:

						if(faradd==0){

							addacall((unsigned int)itok.number,

(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?CALL_NEAR:CALL_32)));

							callloc0();

						} 			/* CALL NEAR */

						else invalidfarcallitem();

						break;

					case tk_dwordvar:

					case tk_longvar:

						i=2;

						if(am32==FALSE&&htok==0)faradd=8;

					case tk_intvar:

					case tk_wordvar:

						i+=2;

						CheckAllMassiv(bufrm,i,&strinf);

						outseg(&itok,2);

						op(0xFF); op(0x10+itok.rm+faradd);

						outaddress(&itok);

						break;

					default:

						preerror("Invalid item for CALL");

						break;

				}

#ifdef OPTVARCONST

				FreeGlobalConst();

#endif

				clearregstat();

				break;

			case a_cbw:

				ClearReg(AX);

				if(am32)op(0x66);

				op(0x98);	//CBW

				break;

			case a_cdq:

				ClearReg(DX);

				op66(r32);

				op(0x99);

				possiblecpu=3;	//CDQ

				break;

			case a_clc:

				op(0xF8);	//CLC

				break;

			case a_cld:

				op(0xFC);	//CLD

				break;

			case a_cli:

				op(0xFA);	//CLI

				break;

			case a_clts:	//CLTS

				outword(0x060F);

				possiblecpu=2;

				break;

			case a_cmc:

				op(0xF5);	//CMC

				break;

			case a_cmpsb:

				ClearReg(SI);

				ClearReg(DI);

				op(0xA6);

				break;

			case a_cmpsw:

				ClearReg(SI);

				ClearReg(DI);

				op66(r16);

				op(0xA7);

				break;

			case a_cmpsd:

				if(ScanTok3()==tk_camma&&tok2==tk_xmmreg){

					xmm3instr(0xC2,0xF2);

					possiblecpu=9;

					next=0;

				}

				else{

					ClearReg(SI);

					ClearReg(DI);

					op66(r32);

					op(0xA7);

					possiblecpu=3;

				}

				break;

			case a_cmpxchg:	//CMPXCHG

				nexttok();

				htok=tok;

				hstok=itok;

				hbuf=bufrm;

				bufrm=NULL;

				hstr=strinf;

				strinf.bufstr=NULL;

				nextexpecting2(tk_camma);

				i=r16;

				ClearReg(AX);

				switch(htok){

					case tk_reg32:

						i=r32;

					case tk_reg:

						ClearReg(hstok.number);

						switch(tok){

							case tk_reg32:

								if(i==r16)goto erreg;

							case tk_reg:

	 							op66(i);

								outword(0xB10F);

								op(128+64+(unsigned int)itok.number*8+hstok.number);

								break;

							case tk_longvar:

							case tk_dwordvar:

								if(i==r16)goto erreg;

							case tk_intvar:

							case tk_wordvar:

#ifdef OPTVARCONST

								ClearVarByNum(&itok);

#endif

								CheckAllMassiv(bufrm,i,&strinf);

	 							op66(i);

								outseg(&itok,3);

								outword(0xB10F);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default:

erreg:

								if(i==r16)wordvalexpected();

								else dwordvalexpected();

								break;

						}

						break;

					case tk_beg:

						ClearReg(hstok.number);

						switch(tok){

							case tk_beg:

								outword(0xB00F);

								op(128+64+(unsigned int)itok.number*8+hstok.number);

								break;

							case tk_charvar:

							case tk_bytevar:

								CheckAllMassiv(bufrm,1,&strinf);

								outseg(&itok,3);

								outword(0xB00F);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default: bytevalexpected(2);

								break;

						}

						break;

					case tk_charvar:

					case tk_bytevar:

#ifdef OPTVARCONST

						ClearVarByNum(&hstok);

#endif

						if(tok!=tk_beg)begexpected(2);

						CheckAllMassiv(hbuf,1,&hstr,&hstok);

						KillVar(hstok.name);

						outseg(&hstok,3);

						outword(0xB00F);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					case tk_longvar:

					case tk_dwordvar:

						if(tok!=tk_reg32)reg32expected(2);

						i=r32;

						goto noint;

					case tk_intvar:

					case tk_wordvar:

						if(tok!=tk_reg)regexpected(2);

noint:

#ifdef OPTVARCONST

						ClearVarByNum(&hstok);

#endif

						CheckAllMassiv(hbuf,i,&hstr,&hstok);

						KillVar(hstok.name);

						op66(i);

						outseg(&hstok,3);

						outword(0xB10F);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					default:

						varexpected(1);

						break;

				}

				possiblecpu=4;

				break;

			case a_cmpxchg8b:	//CMPXCHG8B

				nexttok();

				if(tok!=tk_qwordvar)qwordvalexpected();

#ifdef OPTVARCONST

				ClearVarByNum(&itok);

#endif

				CheckAllMassiv(bufrm,8,&strinf);

				KillVar(itok.name);

				outseg(&itok,3);

				outword(0xc70f);

				op(itok.rm+8);

				outaddress(&itok);

				possiblecpu=5;

				break;

			case a_cwd:

				ClearReg(DX);

				op66(r16);

				op(0x99);	//CWD

				break;

			case a_cwde:

				ClearReg(AX);

				if(!am32)op(0x66);

				op(0x98);

				possiblecpu=3;

				break;

			case a_cpuid:

				ClearReg(AX);

				ClearReg(BX);

				ClearReg(CX);

				ClearReg(DX);

				outword(0xa20f);	//CPUID

				possiblecpu=5;

				break;

			case a_daa:

				ClearReg(AX);

				op(0x27);	//DAA

				break;

			case a_das:

				ClearReg(AX);

				op(0x2F);	//DAS

				break;

			case a_db:	//DB

				dbgact++;

				asmparam=FALSE;

				do{

					i=1;

					nexttok();

					CheckIP();

					if(tok==tk_number){

						hnumber=doconstdwordmath();

						if(tok==tk_id&&strcmp((char *)string,"dup")==0){

							i=hnumber;

							nexttok();

							CheckMinusNum();

							if(tok==tk_number)hnumber=doconstdwordmath();

							else numexpected();

						}

						for(;i!=0;i--)op(hnumber);

					}

					else if(tok==tk_string){

						for(i=0;i<(unsigned int)itok.number;i++)opd(string[i]);

						switch(itok.flag&3){

							case zero_term:

								if(itok.flag&s_unicod)opd(0);

								opd(0);

								break;

							case dos_term:

								if(itok.flag&s_unicod)opd(0);

								opd('$');

								break;

						}

						nexttok();

					}

					else{

						numexpected();

						nexttok();

					}

				}while(tok==tk_camma);

				dbgact--;

				next=0;

				break;

			case a_dd:	//DD

				faradd++;

			case a_dw:	//DW

				DDDW(faradd);

				next=0;

				break;

			case a_enter:	//ENTER

				ClearReg(BP);

				op(0xC8);

				nexttok();

				if(tok==tk_number)outword((unsigned int)doconstlongmath());

				else{

					numexpected(1);

					nexttok();

				}

				expecting2(tk_camma);

				if(tok==tk_number)op((int)doconstlongmath());

				else{

					numexpected(2);

					nexttok();

				}

				next=0;

				possiblecpu=2;

				break;

			case a_emms:	//EMMS

				outword(0x770f);

				possiblecpu=6;

				break;

			case a_imul:	//IMUL

				nexttok();

				if(tok2!=tk_camma){

				ClearReg(AX);

					switch(tok){

						case tk_reg32:

							possiblecpu=3;

							razr=r32;

						case tk_reg:

							ClearReg(DX);

							op66(razr);

						  op(246+1);

							op(128+64+40+(unsigned int)itok.number);

							break;

						case tk_beg:

							op(246);

							op(128+64+40+(unsigned int)itok.number);

							break;

						case tk_charvar:

						case tk_bytevar:

							CheckAllMassiv(bufrm,1,&strinf);

							outseg(&itok,2);

							op(246);

							op(itok.rm+40);

							outaddress(&itok);

							break;

						case tk_longvar:

						case tk_dwordvar:

							CheckAllMassiv(bufrm,4,&strinf);

							possiblecpu=3;

							razr=r32;

						case tk_intvar:

						case tk_wordvar:

							CheckAllMassiv(bufrm,2,&strinf);

							ClearReg(DX);

							op66(razr);

							outseg(&itok,2);

							op(247);

							op(itok.rm+40);

							outaddress(&itok);

							break;

						default: varexpected(1);	break;

					}

				}

				else{

					htok=tok;

					hnumber=itok.number;

					ClearReg(hnumber);

					nextexpecting2(tk_camma);

					possiblecpu=2;

					if(tok2!=tk_camma){

						switch(tok){

							case tk_number:

								switch(htok){

									case tk_reg32:

										possiblecpu=3;

										razr=r32;

									case tk_reg:

										op66(razr);

										if(short_ok(itok.number,TRUE))i=2;	//���⪠� �ଠ

										op(0x69+i);

										op(0xc0+(unsigned int)hnumber+(unsigned int)hnumber*8);

										if(i==2)op(itok.number);

										else{

											if(htok==tk_reg)outword(itok.number);

											else outdword(itok.number);

										}

										break;

									default: reg32regexpected(1);

								}

								break;

							case tk_reg32:

								razr=r32;

							case tk_reg:

								op66(razr);

								possiblecpu=3;

								if(htok!=tok)reg32regexpected(1);

								outword(0xaf0f);

								op(0xc0+(unsigned int)itok.number+(unsigned int)hnumber*8);

								break;

							case tk_longvar:

								tok++;

							case tk_dwordvar:

								if(htok!=tk_reg32)reg32expected(1);

								CheckAllMassiv(bufrm,4,&strinf);

								razr=r32;

								goto imul1;

							case tk_intvar:

								tok++;

							case tk_wordvar:

imul1:

								possiblecpu=3;

								if(htok!=tk_reg&&(tok==tk_intvar||tok==tk_wordvar))regexpected(1);

								CheckAllMassiv(bufrm,2,&strinf);

								op66(razr);

								outseg(&itok,3);

								outword(0xaf0f);

								op(itok.rm+hnumber*8);

								outaddress(&itok);

								break;

							default: varexpected(2);

						}

					}

					else{

						int htok2=tok;

						hstok=itok;

						hbuf=bufrm;

						hstr=strinf;

						strinf.bufstr=NULL;

						bufrm=NULL;

						nextexpecting2(tk_camma);

						if(tok!=tk_number)numexpected(3);

						switch(htok2){

							case tk_reg32:

								possiblecpu=3;

								razr=r32;

							case tk_reg:

								op66(razr);

								if(htok!=htok2)reg32regexpected(2);

								if(short_ok(itok.number,TRUE))i=2;	//���⪠� �ଠ

								op(0x69+i);

								op(0xc0+(unsigned int)hstok.number+(unsigned int)hnumber*8);

								if(i==2)op(itok.number);

								else{

									if(htok==tk_reg)outword(itok.number);

									else outdword(itok.number);

								}

								break;

							case tk_longvar:

								tok++;

							case tk_dwordvar:

								possiblecpu=3;

								if(htok!=tk_reg32)reg32expected(2);

								CheckAllMassiv(hbuf,4,&hstr,&hstok);

								razr=r32;

								goto imul2;

							case tk_intvar:

								tok++;

							case tk_wordvar:

imul2:

								if(htok!=tk_reg&&(htok2==tk_intvar||htok2==tk_wordvar))regexpected(1);

								CheckAllMassiv(hbuf,2,&hstr,&hstok);

								op66(razr);

								if(short_ok(itok.number,TRUE))i=2;	//���⪠� �ଠ

								outseg(&hstok,2);

								op(0x69+i);

								op(hstok.rm+hnumber*8);

								outaddress(&hstok);

								if(i==2)op(itok.number);

								else{

									if(htok==tk_reg)outword(itok.number);

									else outdword(itok.number);

								}

								break;

							default: varexpected(2);

						}

					}

				}

				break;

			case a_in:	//IN

				ClearReg(AX);

				nexttok();

				if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){

					op66(tok==tk_reg?r16:r32);

					if(tok==tk_reg32)possiblecpu=3;

					nexttok();

					expecting(tk_camma);

					if(tok==tk_number){

						op(0xE5);

						asmparam=FALSE;

						if((hnumber=doconstdwordmath())>255)bytedxexpected();

						op(hnumber);

						next = 0;

					}

					else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xED);

					else bytedxexpected();

				}

				else if(tok==tk_beg&&(unsigned int)itok.number==AL){

					nexttok();

					expecting(tk_camma);

					if(tok==tk_number){

						op(0xE4);

						asmparam=FALSE;

						if((hnumber=doconstdwordmath())>255)bytedxexpected();

						op(hnumber);

						next=0;

					}

					else if(tok==tk_reg&&(unsigned int)itok.number==DX)op(0xEC);

					else bytedxexpected();

				}

				else axalexpected();

				break;

			case a_insb:	//INSB

				ClearReg(AX);

				ClearReg(DI);

				op(0x6C);

				possiblecpu=2;

				break;

			case a_insw:	//INSW

				op66(r16);

				possiblecpu=2;

				goto insd;

				break;

			case a_insd:	//INSD

				op66(r32);

				possiblecpu=3;

insd:

				op(0x6D);

				ClearReg(AX);

				ClearReg(DI);

				break;

			case a_int:	//INT

				clearregstat();

				nexttok();

				if(tok==tk_number){

					asmparam=FALSE;

					htok=doconstlongmath();

					if(htok==3)op(0xCC);

					else{

						op(0xCD);

						op(htok);

					}

					next=0;

				}

				else numexpected();

				break;

			case a_into:

				op(0xCE);	//INTO

				break;

			case a_invd:	//INVD

				outword(0x080F);

				possiblecpu=4;

				break;

			case a_invlpg:	//INVLPG

				nexttok();

				switch(tok){

					case tk_longvar:

					case tk_dwordvar:

						CheckAllMassiv(bufrm,4,&strinf);

						goto invlgp;

					case tk_intvar:

					case tk_wordvar:

						CheckAllMassiv(bufrm,2,&strinf);

invlgp:

						outseg(&itok,3);

						outword(0x010F);

						op(itok.rm+0x38);

						outaddress(&itok);

						break;



					case tk_undefofs:

						strcpy(hstok.name,itok.name);

						tok=tk_number;

					case tk_number:

						hnumber=doconstdwordmath();

						outword(0x010f);

						op((am32==FALSE?rm_d16:rm_d32)+0x38);

		 				if(postnumflag&f_reloc)AddReloc();

					 	if(htok==tk_undefofs)AddUndefOff(2,hstok.name);

						if(am32)outdword(hnumber);

						else outword(hnumber);

						next=0;

						break;

					case tk_postnumber:

						outword(0x010F);

						op((am32==FALSE?rm_d16:rm_d32)+0x38);

						(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

						if(am32==FALSE)outword(itok.number);	//�뫮 0

						outdword(itok.number);

						break;



					default:

						varexpected(0); break;

				}

				possiblecpu=4;

				break;

			case a_iret:

#ifdef OPTVARCONST

				ClearLVIC();

#endif

				RestoreStack();

				clearregstat();

				op66(r16);

				op(0xCF);	//IRET

				break;

			case a_iretd:

#ifdef OPTVARCONST

				ClearLVIC();

#endif

				RestoreStack();

				clearregstat();

				op66(r32);

				op(0xCF);	//IRETD

				break;

			case a_jo:

			case a_jno:

			case a_jc:

			case a_jnc:

			case a_jz:

			case a_jnz:

			case a_jna:

			case a_ja:

			case a_js:

			case a_jns:

			case a_jp:

			case a_jnp:

			case a_jl:

			case a_jnl:

			case a_jng:

			case a_jg:

				RestoreStack();

				asmshortjump((htok-a_jo)+0x70,(htok-a_jo)+0x80);

				next=0;

				break;

			case a_jecxz:	//JECXZ

				RestoreStack();

				op67(r32);

				asmshortjump(0xE3,0);

				next=0;

				break;

			case a_jcxz:	//JCXZ

				RestoreStack();

				op67(r16);

				asmshortjump(0xE3,0);

				next=0;

				break;

			case a_jmp:	//JMP

				RestoreStack();

				nexttok();

				faradd=0;

				lastcommand=tk_goto;

				if(stricmp("FAR",itok.name)==0){

					nexttok();

					faradd=8;

				}

				else if(stricmp("NEAR",itok.name)==0)nexttok();

				else if(stricmp("SHORT",itok.name)==0){	 // case insensitive

					nexttok();

					next=(unsigned char)GOTO();

					break;

				}

				next=gotol(faradd);

				break;

			case a_lahf:

				ClearReg(AX);

				op(0x9F);	//LAHF

				break;

			case a_lar:	//LAR

			case a_lsl:	//LSL

				lar_lsl(htok-a_lar+2);

				break;

			case a_leave:	//LEAVE

				RestoreStack();

				op(0xC9);

				ClearReg(BP);

				possiblecpu = 2;

				break;

			case a_lmsw:

				protectinstr(1,0x30);	//LMSW

				break;

			case a_loadall:	// LOADALL 80286 only

				outword(0x050F);

				possiblecpu=2;

				break;

			case a_lodsb:

				ClearReg(SI);

				ClearReg(AX);

				op(0xAC);	//LODSB

				break;

			case a_lodsw:

				op66(r16);

				ClearReg(SI);

				ClearReg(AX);

				op(0xAD);	//LODSW

				break;

			case a_lodsd:

				op66(r32);

				ClearReg(SI);

				ClearReg(AX);

				op(0xAD);

				possiblecpu =3;	//LODSD

				break;

			case a_lock:

				op(0xF0);	//LOCK

				break;

			case a_loop:

				ConstToReg(0,CX,(am32+1)*2);

				op67(r16);

				asmshortjump(0xE2,0);

				next=0;

				break;

			case a_loopd:

				ConstToReg(0,CX,r32);

				possiblecpu=3;

				op67(r32);

				asmshortjump(0xE2,0);

				next=0;

				break;

			case a_loopz:	//LOOPE LOOPZ

				ClearReg(CX);

				asmshortjump(0xE1,0);

				next=0;

				break;

			case a_loopnz:	//LOOPNZ LOOPNE

				ClearReg(CX);

				asmshortjump(0xE0,0);

				next=0;

				break;

			case a_ltr:

				protectinstr(0,0x18);	//LTR

				break;

			case a_str:

				protectinstr(0,0x08);	//STR

				break;

			case a_lgdt:

				next=tabldeckr(0x10);

				break;

			case a_lidt:	//LIDT

				next=tabldeckr(0x18);

				break;

			case a_lldt:

				protectinstr(0,0x10);	//LLDT

				break;

			case a_mov:

				doasmmov();

				next=0;

				break;

			case a_movsb:

				movsb();	//MOVSB

				break;

			case a_movsd:

				if(ScanTok3()==tk_camma&&(tok2==tk_xmmreg||(tok2>=tk_charvar&&tok2<tk_qwordvar))){

					movxmm(0x10,0xf2);

					possiblecpu=9;

				}

				else movsd();	//MOVSD

				break;

			case a_movsw:

				movsw();	//MOVSW

				break;

			case a_movzx:

			case a_movsx:

				asmextend((htok-a_movzx)*8+0xB6);

				break;

			case a_movd:

				movd();	//MOVD

				break;

			case a_movq:

				movq();	//MOVQ

				break;

			case a_nop:

				op(0x90);	//NOP

				break;

			case a_opsiz:	//OPSIZ OPSIZE

				op(0x66);

				possiblecpu=3;

				break;

			case a_out:	//OUT

				nexttok();

				if(tok==tk_number){

					if((hnumber=doconstdwordmath())>255)bytedxexpected();

					expecting2(tk_camma);

					if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){

						op66(tok==tk_reg?r16:r32);

						if(tok==tk_reg32)possiblecpu=3;

						op(0xE7);	op(hnumber);

					}

					else if(tok==tk_beg&&(unsigned int)itok.number==AL){

						op(0xE6);	op(hnumber);

					}

					else axalexpected();

				}

				else if(tok==tk_reg&&(unsigned int)itok.number==DX){

					nextexpecting2(tk_camma);

					if((tok==tk_reg||tok==tk_reg32)&&(unsigned int)itok.number==AX){

						op66(tok==tk_reg?r16:r32);

						if(tok==tk_reg32)possiblecpu=3;

						op(0xEF);

					}

					else if(tok==tk_beg&&(unsigned int)itok.number==AL)op(0xEE);

					else axalexpected();

				}

				else bytedxexpected();

				break;

			case a_outsb:	//OUTSB

				ClearReg(SI);

				op(0x6E);

				possiblecpu=2;

				break;

			case a_outsw:	//OUTSW

				ClearReg(SI);

				op66(r16);

				op(0x6F);

				possiblecpu=2;

				break;

			case a_outsd:	//OUTSD

				ClearReg(SI);

				op66(r32);

				op(0x6F);

				possiblecpu=3;

				break;

			case a_pop:	//POP

				RestoreStack();

				do{

					possiblecpu=0;

					asmparam=TRUE;

					nexttok();

					razr=r16;

					switch(tok){

						case tk_reg32:

							possiblecpu=3;

							razr=r32;

						case tk_reg:

							ClearReg(itok.number);

							op66(razr);

						  op(0x58+(unsigned int)itok.number); break;

						case tk_dwordvar:

							tok--;

						case tk_longvar:

							CheckAllMassiv(bufrm,4,&strinf);

							possiblecpu=3;

							razr=r32;

							goto pop;

						case tk_wordvar:

							tok--;

						case tk_intvar:

							CheckAllMassiv(bufrm,2,&strinf);

pop:

#ifdef OPTVARCONST

							ClearVarByNum(&itok);

#endif

							KillVar(itok.name);

							op66(razr);

							outseg(&itok,2);

							op(0x8F);	op(itok.rm);

							outaddress(&itok);

							break;

						case tk_seg:

							if(itok.number!=CS){

								PopSeg((unsigned int)itok.number);

								break;

							}

						default:

							preerror("Invalid operand for POP");

							break;

					}

					if(cpu<possiblecpu)cpu=possiblecpu;

					asmparam=FALSE;

					addESP-=razr==r16?2:4;

					nexttok();

				}while(tok==tk_camma);

				next=0;

				break;

			case a_popa:	//POPA

				razr=r16;

				possiblecpu=2;

				goto POPAD;

			case a_popad:	//POPAD

				razr=r32;

				possiblecpu=3;

POPAD:

				op66(razr);

				addESP-=razr==r16?16:32;

				RestoreStack();

				clearregstat();

				op(0x61);

				break;

			case a_popf:

				razr=r16;

				goto POPFD;

			case a_popfd:	//POPFD

				razr=r32;

				possiblecpu = 3;

POPFD:

				op66(razr);

				addESP-=razr==r16?2:4;

				RestoreStack();

				op(0x9D);

				break;

			case a_push:	//PUSH

				RestoreStack();

				do{

					asmparam=TRUE;

					nexttok();

					if((razr=Push())==FALSE)preerror("Invalid operand for PUSH");

					asmparam=FALSE;

					addESP+=razr==r16?2:4;

				}while(tok==tk_camma);

				next=0;

				break;

			case a_pusha:	//PUSHA

				razr=r16;

				possiblecpu=2;

				goto PUSHAD;

			case a_pushad:	//PUSHAD

				razr=r32;

				possiblecpu=3;

PUSHAD:

				op66(razr);

				addESP+=razr==r16?16:32;

				RestoreStack();

				op(0x60);

				break;

			case a_pushf:

				razr=r16;

				goto PUSHFD;

			case a_pushfd:	//PUSHFD

				razr=r32;

				possiblecpu=3;

PUSHFD:

				op66(razr);

				RestoreStack();

				op(0x9C);

				addESP+=razr==r16?2:4;

				break;

			case a_pcmpeqd:

			case a_pcmpeqw:

			case a_pcmpeqb:

			case a_packssdw:  //+xmm

			case a_punpckhdq:

			case a_punpckhwd:

			case a_punpckhbw:

			case a_packuswb:    //+xmm

			case a_pcmpgtd:

			case a_pcmpgtw:

			case a_pcmpgtb:

			case a_packsswb:	//+xmm

			case a_punpckldq:

			case a_punpcklwd:

			case a_punpcklbw:

				mmxiii(htok-a_punpcklbw+0x60);

				break;

			case a_pmullw:

				mmxiii(0xD5);	//PMULLW

				break;

			case a_pmuludq:

				mmxiii(0xF4);	//PMULUDQ

				break;

			case a_psubusb:

				mmxiii(0xD8);	//PSUBUSB

				break;

			case a_psubusw:

				mmxiii(0xD9);//PSUBUSW

				break;

			case a_pand:    //+xmm

				mmxiii(0xDB);	//PAND

				break;

			case a_paddusb:	//+xmm

				mmxiii(0xDC);	//PADDUSB

				break;

			case a_paddusw: //+xmm

				mmxiii(0xDD);//PADDUSW

				break;

			case a_pandn:   //+xmm

				mmxiii(0xDF);//PANDN

				break;

			case a_pause:

				outword(0x90F3);

				possiblecpu=9;

				break;

			case a_pmulhw:

				mmxiii(0xE5);	//PMULHW

				break;

			case a_psubsb:

				mmxiii(0xE8);	//PSUBSB

				break;

			case a_psubsw:

				mmxiii(0xE9);//PSUBSW

				break;

			case a_por:

				mmxiii(0xEB);	//POR

				break;

			case a_paddsb:	//+xmm

				mmxiii(0xEC);	//PADDSB

				break;

			case a_paddsw:  //+xmm

				mmxiii(0xED);//PADDSW

				break;

			case a_pxor:

				mmxiii(0xEF);	//PXOR

				break;

			case a_pmaddwd:

				mmxiii(0xF5);	//PMADDWD

				break;

			case a_psubb:

				mmxiii(0xF8);	//PSUBB

				break;

			case a_psubw:

				mmxiii(0xF9);//PSUBW

				break;

			case a_psubd:

				mmxiii(0xFA);//PSUBD

				break;

			case a_psubq:

				mmxiii(0xFB);//PSUBQ

				possiblecpu=9;

				break;

			case a_paddb:   //+xmm

				mmxiii(0xFC);	//PADDB

				break;

			case a_paddw:   //+xmm

				mmxiii(0xFD);//PADDW

				break;

			case a_paddd:   //+xmm

				mmxiii(0xFE);//PADDD

				break;

			case a_paddq:   //+xmm

				mmxiii(0xD4);//PADDQ

				possiblecpu=9;

				break;



			case a_psrlw:

				packMMX(0xD1,0x71,0xd0);	//PSRLW

				next=0;

				break;

			case a_psrld:

				packMMX(0xD2,0x72,0xd0);//PSRLD

				next=0;

				break;

			case a_psrlq:

				packMMX(0xD3,0x73,0xd0);//PSRLQ

				next=0;

				break;

			case a_psraw:

				packMMX(0xE1,0x71,0xe0);	//PSRAW

				next=0;

				break;

			case a_psrad:

				packMMX(0xE2,0x72,0xe0);//PSRAD

				next=0;

				break;

			case a_psllw:

				packMMX(0xF1,0x71,0xf0);	//PSLLW

				next=0;

				break;

			case a_pslld:

				packMMX(0xF2,0x72,0xf0);//PSLLD

				next=0;

				break;

			case a_psllq:

				packMMX(0xF3,0x73,0xf0);//PSLLQ

				next=0;

				break;

			case a_pslldq:

				shiftxmm(7);

				next=0;

				possiblecpu=9;

				break;

			case a_psrldq:

				shiftxmm(3);

				next=0;

				possiblecpu=9;

				break;

			case a_rdmsr:

				ClearReg(AX);

				ClearReg(DX);

				outword(0X320F);

				possiblecpu=5;

				break;

			case a_rdtsc:

				outword(0X310F);

				possiblecpu=5;

				break;

			case a_rep:

	      op(0xF3);//REP REPE REPZ

				ClearReg(CX);

				break;

			case a_repnz:

	      op(0xF2);	//REPNE REPNZ

				ClearReg(CX);

				break;

			case a_ret:	//RET

#ifdef OPTVARCONST

				ClearLVIC();

#endif

				RestoreStack();

				clearregstat();

				next=0;

				if(tok2==tk_number){

//					usedirectiv=TRUE;

					nexttok();

					op(0xC2);

				 	asmparam=FALSE;

					outword((unsigned int)doconstlongmath());

//					usedirectiv=FALSE;

				}

				else{

					op(0xC3);

					nexttok();

				}

				break;

			case a_retf:

#ifdef OPTVARCONST

				ClearLVIC();

#endif

				RestoreStack();

				clearregstat();

				next=0;

				if(tok2==tk_number){

					nexttok();

					op(0xCA);

				 	asmparam=FALSE;

					outword((unsigned int)doconstlongmath());

				}

				else{

					op(0xCB);

					nexttok();

				}//RETF

				break;

			case a_rsm:	//RSM

				outword(0Xaa0F);

				possiblecpu=5;

				break;

			case a_sahf:

				op(0x9E);	//SAHF

				break;

			case a_scasb:

				op(0xAE);	//SCASB

				ClearReg(DI);

				break;

			case a_scasw:

				op66(r16);

				op(0xAF);  //SCASW

				ClearReg(DI);

				break;

			case a_scasd:	//SCASD

				op66(r32);

				op(0xAF);

				possiblecpu=3;

				ClearReg(DI);

				break;

			case a_smsw:

				protectinstr(1,0x20);	//SMSW

				break;

			case a_stc:

				op(0xF9);	//STC

				break;

			case a_std:

				op(0xFD);	//STD

				break;

			case a_sti:

				op(0xFB);	//STI

				break;

			case a_stosb:

				stosb();	//STOSB

				break;

			case a_stosw:

				stosw();	//STOSW

				break;

			case a_stosd:

				stosd();	//STOSD

				break;

			case a_seto:

			case a_setno:

			case a_setc:

			case a_setnc:

			case a_setz:

			case a_setnz:

			case a_setna:

			case a_seta:

			case a_sets:

			case a_setns:

			case a_setp:

			case a_setnp:

			case a_setl:

			case a_setnl:

			case a_setng:

			case a_setg:

				i=htok-a_seto;

				nexttok();

				switch(tok){

					case tk_beg:

						ClearReg(itok.number%4);

						op(0xf);

						op(0x90+i);

						op(0xc0+(unsigned int)itok.number);

						break;

					case tk_charvar:

					case tk_bytevar:

						CheckAllMassiv(bufrm,1,&strinf);

						KillVar(itok.name);

						outseg(&itok,3);

						op(0xf);

						op(0x90+i);

						op(itok.rm);

						outaddress(&itok);

						break;

					default: bytevalexpected(0);

				}

				possiblecpu=3;

				break;

			case a_sgdt:

				next=tabldeckr(0);

				break;

			case a_sidt:

				next=tabldeckr(0x8);

				break;

			case a_sldt:

				protectinstr(0,0);	//SLDT

				break;

			case a_fwait:	//FWAIT

			case a_wait:

				fwait();//WAIT

				break;

			case a_wbinvd:	//WBINVD

				outword(0x090F);

				possiblecpu=4;

				break;

			case a_wrmsr:	//WRMSR

				outword(0x300F);

				possiblecpu=5;

				break;

			case a_xadd:	//XADD

				nexttok();

				hstok=itok;

				htok=tok;

				hbuf=bufrm;

				bufrm=NULL;

				hstr=strinf;

				strinf.bufstr=NULL;

				nextexpecting2(tk_camma);

				switch(htok){

					case tk_reg32:

						razr=r32;

					case tk_reg:

						switch(tok){

							case tk_reg32:

								if(razr==r16)goto erxreg;

							case tk_reg:

								RegToReg(itok.number,hstok.number,razr);

								ClearReg(hstok.number);

								op66(razr);

								outword(0xC10F);

								op(128+64+(unsigned int)itok.number*8+hstok.number);

								break;

							case tk_longvar:

							case tk_dwordvar:

								if(razr==r16)goto erxreg;

							case tk_intvar:

							case tk_wordvar:

								KillVar(hstok.name);

								/*if(bufrm==0&&strinf.bufstr==NULL)*/AddRegVar(hstok.number,razr,&itok);

								CheckAllMassiv(bufrm,razr,&strinf);

								op66(razr);

								outseg(&itok,3);

								outword(0xC10F);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default:

erxreg:

								wordvalexpected(); break;

						}

						break;

					case tk_beg:

						switch(tok){

							case tk_beg:

								RegToReg(itok.number,hstok.number,r8);

								ClearReg(hstok.number%4);

								outword(0xC00F);

								op(128+64+(unsigned int)itok.number*8+hstok.number);

								break;

							case tk_charvar:

							case tk_bytevar:

								KillVar(hstok.name);

								/*if(bufrm==0&&strinf.bufstr==NULL)*/AddRegVar(hstok.number,r8,&itok);

								CheckAllMassiv(bufrm,1,&strinf);

								outseg(&itok,3);

								outword(0xC00F);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default: bytevalexpected(2); break;

						}

						break;

					case tk_charvar:

					case tk_bytevar:

						if(tok!=tk_beg)begexpected(2);

						CheckAllMassiv(hbuf,1,&hstr,&hstok);

						ClearReg(itok.number);

						KillVar(hstok.name);

						outseg(&hstok,3);

						outword(0xC00F);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					case tk_longvar:

					case tk_dwordvar:

						if(tok!=tk_reg32)reg32expected(2);

						razr=r32;

						goto nointxadd;

					case tk_intvar:

					case tk_wordvar:

						if(tok!=tk_reg)regexpected(1);

nointxadd:

						CheckAllMassiv(hbuf,razr,&hstr,&hstok);

						ClearReg(itok.number);

						KillVar(hstok.name);

						op66(razr);

						outseg(&hstok,3);

						outword(0xC10F);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					default: varexpected(1); break;

				}

				possiblecpu=4;

				break;

			case a_xchg:	//XCHG

				nexttok();

				htok=tok;

				hstok=itok;

				hbuf=bufrm;

				bufrm=NULL;

				hstr=strinf;

				strinf.bufstr=NULL;

				nextexpecting2(tk_camma);

				switch(htok){

					case tk_reg32:

						razr=r32;

						possiblecpu=3;

					case tk_reg:

						switch(tok){

							case tk_reg32:

								if(razr==r16)goto erregx;

							case tk_reg:

								op66(razr);

								RegSwapReg(hstok.number,itok.number,razr);

								if(hstok.number==AX)op(0x90+(unsigned int)itok.number);

								else if((unsigned int)itok.number==AX)op(0x90+hstok.number);

								else{

									op(0x87);

									op(128+64+(unsigned int)itok.number*8+hstok.number);

								}

								break;

							case tk_longvar:

							case tk_dwordvar:

								if(razr==r16)goto erregx;

							case tk_intvar:

							case tk_wordvar:

								CheckAllMassiv(bufrm,razr,&strinf);

								KillVar(itok.name);

								IDZToReg(itok.name,hstok.number,razr);

								op66(razr);

								outseg(&itok,2);

								op(0x87);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default:

erregx:

								wordvalexpected(); break;

						}

						break;

					case tk_beg:

						switch(tok){

							case tk_beg:

								RegSwapReg(hstok.number,itok.number,r8);

								op(0x86);

								op(128+64+(unsigned int)itok.number*8+hstok.number);

								break;

							case tk_charvar:

							case tk_bytevar:

								CheckAllMassiv(bufrm,1,&strinf);

								KillVar(itok.name);

								IDZToReg(itok.name,hstok.number,r8);

								outseg(&itok,2);

								op(0x86);

								op(itok.rm+hstok.number*8);

								outaddress(&itok);

								break;

							default: bytevalexpected(2); break;

						}

						break;

					case tk_charvar:

					case tk_bytevar:

						if(tok!=tk_beg)begexpected(2);

						CheckAllMassiv(hbuf,1,&hstr,&hstok);

						KillVar(hstok.name);

						IDZToReg(hstok.name,itok.number,r8);

						outseg(&hstok,2);

						op(0x86);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					case tk_longvar:

					case tk_dwordvar:

						razr=r32;

						possiblecpu=3;

						if(tok!=tk_reg32)reg32expected(2);

						goto nointx;

					case tk_intvar:

					case tk_wordvar:

						if(tok!=tk_reg)regexpected(2);

nointx:

		 				CheckAllMassiv(hbuf,razr,&hstr,&hstok);

						KillVar(hstok.name);

						IDZToReg(hstok.name,itok.number,razr);

						op66(razr);

						outseg(&hstok,2);

						op(0x87);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

						break;

					default: varexpected(1); break;

				}

				break;

			case a_xlat:

				ClearReg(AX);

				op(0xD7);	//XLAT

				break;

			case a_hlt:

	      op(0xF4);	//HLT

				break;

			case a_verr:

				protectinstr(0,0x20);	//VERR

				break;

			case a_verw:

				protectinstr(0,0x28);	//VERW

				break;

			case a_test:	//TEST

				if(iTest()==FALSE)invalidoperand(0);

				next=0;

				break;

			case a_fcom:	//FCOM

				FpuType1(0x10);

				break;

			case a_fcomp:	//FCOMP

				FpuType1(0x18);

				break;

			case a_fadd:	//FADD

				FpuType2(0,0);

				break;

			case a_fdiv:	//FDIV

				FpuType2(0x38,0x30);

				break;

			case a_fdivr:	//FDIVR

				FpuType2(0x30,0x38);

				break;

			case a_fmul:	//FMUL

				FpuType2(0x8,0x8);

				break;

			case a_fsub:	//FSUB

				FpuType2(0x28,0x20);

				break;

			case a_fsubr:	//FSUBR

				FpuType2(0x20,0x28);

				break;

			case a_faddp:	//FADDP

				FpuType3(0xDE,0);

				break;

			case a_fdivp:	//FDIVP

				FpuType3(0xDE,0x38);

				break;

			case a_fdivrp:	//FDIVRP

				FpuType3(0xDE,0x30);

				break;

			case a_ffree:	//FFREE

				FpuType3(0xDD,0);

				break;

			case a_fmulp:	//FMULP

				FpuType3(0xDE,8);

				break;

			case a_fsubp:	//FSUBP

				FpuType3(0xDE,0x28);

				break;

			case a_fsubrp:	//FSUBRP

				FpuType3(0xDE,0x20);

				break;

			case a_fucom:	//FUCOM

				FpuType3(0xDD,0x20);

				break;

			case a_fucomp:	//FUCOMP

				FpuType3(0xDD,0x28);

				break;

			case a_fxch:	//FXCH

				FpuType3(0xD9,8);

				break;



			case a_fiadd:	//FIADD

				FpuType4(0,0);

				break;

			case a_ficom:	//FICOM

				FpuType4(0,0x10);

				break;

			case a_ficomp:	//FICOMP

				FpuType4(0,0x18);

				break;

			case a_fidiv:	//FIDIV

				FpuType4(0,0x30);

				break;

			case a_fidivr:	//FIDIVR

				FpuType4(0,0x38);

				break;

			case a_fild:	//FILD

				FpuType4(1,0);

				break;

			case a_fimul:	//FIMUL

				FpuType4(0,8);

				break;

			case a_fist:	//FIST

				FpuType4(1,0x10);

				break;

			case a_fistp:	//FISTP

				FpuType4(1,0x18);

				break;

			case a_fisub:	//FISUB

				FpuType4(0,0x20);

				break;

			case a_fisubr:	//FISUBR

				FpuType4(0,0x28);

				break;



			case a_fld:	//FLD

				FpuType5(0xD9,0);

				break;

			case a_fst:	//FST

				FpuType5(0xDD,0x10);

				break;

			case a_fstp:	//FSTP

				FpuType5(0xDD,0x18);

				break;



			case a_fbld:	//FBLD

				FpuType6(0xDF,0X20);

				break;

			case a_fbstp:	//FBSTP

				FpuType6(0xDF,0X30);

				break;

			case a_fildq:	//FILDQ

				FpuType6(0xDF,0x28);

				break;

			case a_fldenv:	//FLDENV ��� �����������

				FpuType6(0xD9,0x20);

				break;

			case a_frstor:	//FRSTOR ��� �����������

				FpuType6(0xDD,0x20);

				break;

			case a_fsave:	//FSAVE ��� �����������

				fwait();

			case a_fnsave:	//FNSAVE ��� �����������

				FpuType6(0xDD,0x30);

				break;

			case a_fstenv:	//FSTENV ��� �����������

				fwait();

			case a_fnstenv:	//FNSTENV ��� �����������

				FpuType6(0xD9,0x30);

				break;



			case a_fldcw:	//FLDCW

				FpuType7(0x28);

				break;

			case a_fstcw:	//FSTCW

				fwait();

			case a_fnstcw:	//FNSTCW

				FpuType7(0x38);

				break;



			case a_f2xm1:

				outword(0xf0d9);	//F2XM1

				possiblecpu=2;

				break;

			case a_fabs:

				outword(0xE1D9);	//FABS

				break;

			case a_fchs:

				outword(0xE0D9);	//FCHS

				break;

			case a_fclex:	//FCLEX

				fwait();

//				outword(0xE2DB);

//				break;

			case a_fnclex:

				outword(0xE2DB);	//FNCLEX

				break;

			case a_fcompp:

				outword(0xD9DE);	//FCOMPP

				break;

			case a_fcos:	//FCOS

				outword(0xFFD9);

				possiblecpu=3;

				break;

			case a_fdecstr:

				outword(0xF6D9);	//FDECSTP

				break;

			case a_fdisi:

				fwait();

			case a_fndisi:

				outword(0xE1DB);	//FDISI

				break;

			case a_feni:

				fwait();

			case a_fneni:

				outword(0xE0DB);	//FENI

				break;

			case a_fincstr:

				outword(0xF7D9);	//FINCSTP

				break;

			case a_finit:     	//FINIT

				fwait();

			case a_fninit:

				outword(0xE3DB);	//FNINIT

				break;

			case a_fldlg2:

				outword(0xECD9);	//FLDLG2

				break;

			case a_fldln2:

				outword(0xEDD9);	//FLDLN2

				break;

			case a_fldl2e:

				outword(0xEAD9);	//FLDL2E

				break;

			case a_fldl2t:

				outword(0xE9D9);	//FLDL2T

				break;

			case a_fldpi:

				outword(0xEBD9);	//FLDPI

				break;

			case a_fldz:

				outword(0xEED9);	//FLDZ

				break;

			case a_fld1:

				outword(0xE8D9);	//FLD1

				break;

			case a_fnop:

				outword(0xD0D9);	//FNOP

				break;

			case a_fpatan:

				outword(0xF3D9);	//FPATAN

				break;

			case a_fprem:

				outword(0xF8D9);	//FPREM

				break;

			case a_fprem1:

				outword(0xF5D9);	//FPREM1

				possiblecpu=3;

				break;

			case a_fptan:

				outword(0xF2D9);	//FPTAN

				break;

			case a_frndint:

				outword(0xFCD9);	//FRNDINT

				break;

			case a_fsetpm:

				fwait();

			case a_fnsetpm:

				outword(0xE4DB);	//FSETPM

				possiblecpu=2;

				break;

			case a_fscale:

				outword(0XFDD9);	//FSCALE

				break;

			case a_fsin:	//FSIN

				outword(0xFED9);

				possiblecpu=3;

				break;

			case a_fsincos:	//FSINCOS

				outword(0xFBD9);

				possiblecpu=3;

				break;

			case a_fsqrt:

				outword(0xFAD9);	//FSQRT

				break;

			case a_fstsw:	//FSTSW

				fwait();

			case a_fnstsw:	//FNSTSW

				nexttok();

				switch(tok){

					case tk_wordvar:

					case tk_intvar:

						CheckAllMassiv(bufrm,2,&strinf);

						KillVar(itok.name);

						outseg(&itok,2);

						op(0xDD);

						op(itok.rm+0x38);

						outaddress(&itok);

						break;

					case tk_reg:

						if(itok.number==0)outword(0xe0df);

						else preerror("Use only AX");

						ClearReg(AX);

						break;

					default: wordvalexpected();

				}

				break;

			case a_ftst:

				outword(0xE4D9);	//FTST

				break;

			case a_fucompp:	//FUCOMPP

				outword(0xE9DA);

				possiblecpu=3;

				break;

			case a_fxam:

				outword(0xE5D9);	//FXAM

				break;

			case a_fxtract:

				outword(0xF4D9);	//FXTRACT

				break;

			case a_fyl2x:

				outword(0xF1D9);	//FYL2X

				break;

			case a_fyl2xp1:

				outword(0xF9D9);	//FYL2XP1

				break;

			case a_ud2:

				outword(0x0B0F);	//UD2

				possiblecpu=7;

				break;

			case a_sysenter:

				outword(0x340F);	//SYSENTER

				possiblecpu=7;

				break;

			case a_sysexit:

				outword(0x350F);	//SYSEXIT

				possiblecpu=7;

				break;

			case a_rdpmc:

				outword(0x330F);	//RDPMC

				possiblecpu=7;

				break;

			case a_fcmovnu:

				i+=8;

			case a_fcmovnbe:

				i+=8;

			case a_fcmovne:

				i+=8;

			case a_fcmovnb:

				FpuType8(0xDB,i);

				break;

			case a_fcmovu:

				i+=8;

			case a_fcmovbe:

				i+=8;

			case a_fcmove:

				i+=8;

			case a_fcmovb:

				FpuType8(0xDA,i);

				break;

			case a_fcomi:	//FCOMI

				i+=8;

			case a_fucomi:

				FpuType8(0xDB,i+0x28);

				break;

			case a_fcomip:

				i+=8;

			case a_fucomip:

				FpuType8(0xDF,i+0x28);

				break;

			case a_cmovo:

			case a_cmovno:

			case a_cmovc:

			case a_cmovnc:

			case a_cmovz:

			case a_cmovnz:

			case a_cmovna:

			case a_cmova:

			case a_cmovs:

			case a_cmovns:

			case a_cmovp:

			case a_cmovnp:

			case a_cmovl:

			case a_cmovnl:

			case a_cmovng:

			case a_cmovg:

				cmov(htok-a_cmovo);

				possiblecpu=7;

				break;

			case a_lfence:	//LFENCE

				outword(0xAE0F);

				op(0xE8);

				possiblecpu=9;

				break;

			case a_mfence:	//MFENCE

				outword(0xAE0F);

				op(0xF0);

				possiblecpu=9;

				break;

			case a_sfence:	//SFENCE

				outword(0xAE0F);

				op(0xF8);

				possiblecpu=8;

				break;

			case a_maskmovq:	//MASKMOVQ

				nexttok();

				hnumber=itok.number;

				if(tok!=tk_mmxreg)mmxregexpected(1);

				nextexpecting2(tk_camma);

				if(tok!=tk_mmxreg)mmxregexpected(2);

				outword(0xF70F);

				op(0xC0+hnumber+itok.number*8);

				possiblecpu=8;

				break;

			case a_movntq:	//MOVNTQ

				movxmm3(0xE7,0,tk_mmxreg);

				possiblecpu=8;

				break;

			case a_pavgb:

				mmxiii(0xE0);

				break;

			case a_pavgw:

				mmxiii(0xE3);

				break;

			case a_pmaxub:

				mmxiii(0xDE);

				break;

			case a_pmaxsw:

				mmxiii(0xEE);

				break;

			case a_pminub:

				mmxiii(0xDA);

				break;

			case a_pminsw:

				mmxiii(0xEA);

				break;

			case a_pmulhuw:

				mmxiii(0xE4);

				break;

			case a_psadbw:

				mmxiii(0xF6);

				break;

			case a_prefetcht0:

				prefetch(0x18,1);

				possiblecpu=8;

				break;

			case a_prefetcht1:

				prefetch(0x18,2);

				possiblecpu=8;

				break;

			case a_prefetcht2:

				prefetch(0x18,3);

				possiblecpu=8;

				break;

			case a_prefetchnta:

				prefetch(0x18,0);

				possiblecpu=8;

				break;

			case a_pextrw:

				pextrw();

				next=0;

				break;

			case a_pinsrw:

				pinsrw();

				next=0;

				break;

			case a_pmovmskb:

				nexttok();

				if(tok!=tk_reg32)reg32expected(1);

				htok=itok.number;

				ClearReg(htok);

				nextexpecting2(tk_camma);

				if(tok==tk_xmmreg){

					op(0x66);

					possiblecpu=9;

				}

				else{

					possiblecpu=8;

					if(tok!=tk_mmxreg)mmxregexpected(2);

				}

				outword(0xD70F);

				op(rm_mod11+htok*8+itok.number);

				break;

			case a_pshufw:

				pshufw();

				next=0;

				possiblecpu=8;

				break;

			case a_pshufd:

				xmm3instr(0x70,0x66);

				possiblecpu=9;

				next=0;

				break;

			case a_pshufhw:

				xmm3instr(0x70,0xf3);

				possiblecpu=9;

				next=0;

				break;

			case a_pshuflw:

				xmm3instr(0x70,0xf2);

				possiblecpu=9;

				next=0;

				break;

			case a_addpd:

				xmminstr(0x58,0x66);

				possiblecpu=9;

				break;

			case a_addps:

				xmminstr(0x58,0);

				possiblecpu=8;

				break;

			case a_addsd:

				xmminstr(0x58,0xF2);

				possiblecpu=9;

				break;

			case a_addss:

				xmminstr(0x58,0xF3);

				possiblecpu=8;

				break;

			case a_addsubpd:

				xmminstr(0xD0,0x66);

				possiblecpu=9;

				break;

			case a_addsubps:

				xmminstr(0xD0,0xF2);

				possiblecpu=9;

				break;

			case a_andnpd:

				xmminstr(0x55,0x66);

				possiblecpu=9;

				break;

			case a_andnps:

				xmminstr(0x55,0);

				possiblecpu=8;

				break;

			case a_andpd:

				xmminstr(0x54,0x66);

				possiblecpu=9;

				break;

			case a_andps:

				xmminstr(0x54,0);

				possiblecpu=8;

				break;

			case a_comisd:

				xmminstr(0x2F,0x66);

				possiblecpu=9;

				break;

			case a_comiss:

				xmminstr(0x2F,0);

				possiblecpu=8;

				break;

			case a_divps:

				xmminstr(0x5E,0);

				possiblecpu=8;

				break;

			case a_divsd:

				xmminstr(0x5E,0xf2);

				possiblecpu=9;

				break;

			case a_divss:

				xmminstr(0x5E,0xF3);

				possiblecpu=8;

				break;

			case a_haddpd:

				xmminstr(0x7C,0x66);

				possiblecpu=9;

				break;

			case a_haddps:

				xmminstr(0x7C,0xF2);

				possiblecpu=9;

				break;

			case a_hsubpd:

				xmminstr(0x7D,0x66);

				possiblecpu=9;

				break;

			case a_hsubps:

				xmminstr(0x7D,0xF2);

				possiblecpu=9;

				break;

			case a_maskmovdqu:

				xmm2xmm(0xf7,0x66);

				possiblecpu=9;

				break;

			case a_maxpd:

				xmminstr(0x5f,0x66);

				possiblecpu=9;

				break;

			case a_maxps:

				xmminstr(0x5F,0);

				possiblecpu=8;

				break;

			case a_maxsd:

				xmminstr(0x5f,0xf2);

				possiblecpu=9;

				break;

			case a_maxss:

				xmminstr(0x5F,0xF3);

				possiblecpu=8;

				break;

			case a_minpd:

				xmminstr(0x5d,0x66);

				possiblecpu=9;

				break;

			case a_minps:

				xmminstr(0x5D,0);

				possiblecpu=8;

				break;

			case a_minsd:

				xmminstr(0x5d,0xf2);

				possiblecpu=9;

				break;

			case a_minss:

				xmminstr(0x5D,0xF3);

				possiblecpu=8;

				break;

			case a_mulpd:

				xmminstr(0x59,0x66);

				possiblecpu=9;

				break;

			case a_mulps:

				xmminstr(0x59,0);

				possiblecpu=8;

				break;

			case a_mulsd:

				xmminstr(0x59,0xF2);

				possiblecpu=9;

				break;

			case a_mulss:

				xmminstr(0x59,0xF3);

				possiblecpu=8;

				break;

			case a_orpd:

				xmminstr(0x56,0x66);

				possiblecpu=9;

				break;

			case a_orps:

				xmminstr(0x56,0);

				possiblecpu=8;

				break;

			case a_rcpps:

				xmminstr(0x53,0);

				possiblecpu=8;

				break;

			case a_rcpss:

				xmminstr(0x53,0xF3);

				possiblecpu=8;

				break;

			case a_rsqrtps:

				xmminstr(0x52,0);

				possiblecpu=8;

				break;

			case a_rsqrtss:

				xmminstr(0x52,0xF3);

				possiblecpu=8;

				break;

			case a_sqrtpd:

				xmminstr(0x51,0x66);

				possiblecpu=9;

				break;

			case a_sqrtps:

				xmminstr(0x51,0);

				possiblecpu=8;

				break;

			case a_sqrtsd:

				xmminstr(0x51,0xf2);

				possiblecpu=9;

				break;

			case a_sqrtss:

				xmminstr(0x51,0xF3);

				possiblecpu=8;

				break;

			case a_subpd:

				xmminstr(0x5C,0x66);

				possiblecpu=9;

				break;

			case a_subps:

				xmminstr(0x5C,0);

				possiblecpu=8;

				break;

			case a_subsd:

				xmminstr(0x5C,0xF2);

				possiblecpu=9;

				break;

			case a_subss:

				xmminstr(0x5C,0xF3);

				possiblecpu=8;

				break;

			case a_ucomisd:

				xmminstr(0x2E,0x66);

				possiblecpu=9;

				break;

			case a_ucomiss:

				xmminstr(0x2E,0);

				possiblecpu=8;

				break;

			case a_unpckhpd:

				xmminstr(0x15,0x66);

				possiblecpu=9;

				break;

			case a_unpckhps:

				xmminstr(0x15,0);

				possiblecpu=8;

				break;

			case a_unpcklpd:

				xmminstr(0x14,0x66);

				possiblecpu=9;

				break;

			case a_unpcklps:

				xmminstr(0x14,0);

				possiblecpu=8;

				break;

			case a_xorpd:

				xmminstr(0x57,0x66);

				possiblecpu=9;

				break;

			case a_xorps:

				xmminstr(0x57,0);

				possiblecpu=8;

				break;

			case a_cmppd:

				xmm3instr(0xC2,0x66);

				possiblecpu=9;

				next=0;

				break;

			case a_cmpeqpd:

			case a_cmpltpd:

			case a_cmplepd:

			case a_cmpunordpd:

			case a_cmpneqpd:

			case a_cmpnltpd:

			case a_cmpnlepd:

			case a_cmpordpd:

				xmminstr(0xC2,0x66);

				possiblecpu=9;

				op(htok-a_cmpeqpd);

				break;

			case a_cmpps:

				xmm3instr(0xC2,0);

				possiblecpu=8;

				next=0;

				break;

			case a_cmpeqps:

			case a_cmpltps:

			case a_cmpleps:

			case a_cmpunordps:

			case a_cmpneqps:

			case a_cmpnltps:

			case a_cmpnleps:

			case a_cmpordps:

				xmminstr(0xC2,0);

				possiblecpu=9;

				op(htok-a_cmpeqps);

				break;

			case a_cmpss:

				xmm3instr(0xC2,0xF3);

				possiblecpu=8;

				next=0;

				break;

			case a_cmpeqss:

			case a_cmpltss:

			case a_cmpless:

			case a_cmpunordss:

			case a_cmpneqss:

			case a_cmpnltss:

			case a_cmpnless:

			case a_cmpordss:

				xmminstr(0xC2,0xF3);

				possiblecpu=9;

				op(htok-a_cmpeqss);

				break;

			case a_cmpeqsd:

			case a_cmpltsd:

			case a_cmplesd:

			case a_cmpunordsd:

			case a_cmpneqsd:

			case a_cmpnltsd:

			case a_cmpnlesd:

			case a_cmpordsd:

				xmminstr(0xC2,0xF2);

				op(htok-a_cmpeqsd);

				possiblecpu=9;

				break;

			case a_shufpd:

				xmm3instr(0xC6,0x66);

				possiblecpu=9;

				next=0;

				break;

			case a_shufps:

				xmm3instr(0xC6,0);

				possiblecpu=8;

				next=0;

				break;

			case a_cvtdq2pd:

				xmminstr(0xE6,0xF3);

				possiblecpu=9;

				break;

			case a_cvtdq2ps:

				xmminstr(0x5B,0);

				possiblecpu=9;

				break;

			case a_cvtpd2dq:

				xmminstr(0xE6,0xF2);

				possiblecpu=9;

				break;

			case a_cvtpd2pi:

				xmminstr(0x2d,0x66,tk_mmxreg,tk_xmmreg);

				possiblecpu=9;

				break;

			case a_cvtpd2ps:

				xmminstr(0x5a,0x66);

				possiblecpu=9;

				break;

			case a_cvtpi2pd:

				xmminstr(0x2a,0x66,tk_xmmreg,tk_mmxreg);

				possiblecpu=9;

				break;

			case a_cvtpi2ps:

				xmminstr(0x2a,0,tk_xmmreg,tk_mmxreg);

				possiblecpu=8;

				break;

			case a_cvtps2dq:

				xmminstr(0x5b,0x66);

				possiblecpu=9;

				break;

			case a_cvtps2pd:

				xmminstr(0x5a,0);

				possiblecpu=9;

				break;

			case a_cvtsi2ss:

				xmminstr(0x2a,0xf3,tk_xmmreg,tk_reg32);

				possiblecpu=8;

				break;

			case a_cvtps2pi:

				xmminstr(0x2d,0,tk_mmxreg,tk_xmmreg);

				possiblecpu=9;

				break;

			case a_cvtsd2si:

				xmminstr(0x2d,0xf2,tk_reg32,tk_xmmreg);

				possiblecpu=9;

				break;

			case a_cvtsd2ss:

				xmminstr(0x5a,0xf2);

				possiblecpu=9;

				break;

			case a_cvtsi2sd:

				xmminstr(0x2a,0xf2,tk_xmmreg,tk_reg32);

				possiblecpu=9;

				break;

			case a_cvtss2sd:

				xmminstr(0x5a,0xf3);

				possiblecpu=9;

				break;

			case a_cvtss2si:

				xmminstr(0x2d,0xf3,tk_reg32,tk_xmmreg);

				possiblecpu=8;

				break;

			case a_cvttpd2pi:

				xmminstr(0x2c,0x66,tk_mmxreg,tk_xmmreg);

				possiblecpu=9;

				break;

			case a_cvttpd2dq:

				xmminstr(0xE6,0x66);

				possiblecpu=9;

				break;

			case a_cvttps2dq:

				xmminstr(0x5B,0xF3);

				possiblecpu=9;

				break;

			case a_cvttps2pi:

				xmminstr(0x2c,0,tk_mmxreg,tk_xmmreg);

				possiblecpu=8;

				break;

			case a_cvttsd2si:

				xmminstr(0x2C,0xF2,tk_reg32,tk_xmmreg);

				possiblecpu=9;

				break;

			case a_cvttss2si:

				xmminstr(0x2C,0xF3,tk_reg32,tk_xmmreg);

				possiblecpu=8;

				break;

			case a_divpd:

				xmminstr(0x5E,0x66);

				possiblecpu=9;

				break;

			case a_punpckhqdq:

				xmminstr(0x6D,0x66);

				possiblecpu=9;

				break;

			case a_punpcklqdq:

				xmminstr(0x6C,0x66);

				possiblecpu=9;

				break;

			case a_fxrstor:

				prefetch(0xAE,1);

				possiblecpu=8;

				break;

			case a_fxsave:

				prefetch(0xAE,0);

				possiblecpu=8;

				break;

			case a_ldmxcsr:

				prefetch(0xAE,2);

				possiblecpu=8;

				break;

			case a_stmxcsr:

				prefetch(0xAE,3);

				possiblecpu=8;

				break;

			case a_clflush:

				prefetch(0xAE,7);

				possiblecpu=9;

				break;

			case a_monitor:

				outword(0x010F);

				op(0xc8);

				possiblecpu=9;

				break;

			case a_mwait:

				outword(0x010F);

				op(0xc9);

				possiblecpu=9;

				break;

			case a_lddqu:

				movxmm4(0xF0,0xF2);

				possiblecpu=9;

				break;

			case a_movhlps:

				xmm2xmm(0x12);

				possiblecpu=8;

				break;

			case a_movlhps:

				xmm2xmm(0x16);

				possiblecpu=8;

				break;

			case a_movmskps:

				xmm2xmm(0x50,0,tk_reg32);

				possiblecpu=8;

				break;

			case a_movntdq:

				movxmm3(0xE7,0x66);

				possiblecpu=9;

				break;

			case a_movntpd:

				movxmm3(0x2B,0x66);

				possiblecpu=9;

				break;

			case a_movntps:

				movxmm3(0x2b,0);

				possiblecpu=8;

				break;

			case a_movapd:

				movxmm(0x28,0x66);

				possiblecpu=9;

				break;

			case a_movaps:

				movxmm(0x28,0);

				possiblecpu=8;

				break;

			case a_movdqa:

				movxmm(0x6f,0x66,0x10);

				possiblecpu=9;

				break;

			case a_movddup:

				xmminstr(0x12,0xF2);

				possiblecpu=9;

				break;

			case a_movshdup:

				xmminstr(0x16,0xF3);

				possiblecpu=9;

				break;

			case a_movsldup:

				xmminstr(0x12,0xF3);

				possiblecpu=9;

				break;

			case a_movdqu:

				movxmm(0x6f,0xf3,0x10);

				possiblecpu=9;

				break;

			case a_movdq2q:

				xmm2xmm(0xd6,0xf2,tk_mmxreg);

				possiblecpu=9;

				break;

			case a_movhpd:

				movxmm2(0x16,0x66);

				possiblecpu=9;

				break;

			case a_movlpd:

				movxmm2(0x12,0x66);

				possiblecpu=9;

				break;

			case a_movmskpd:

				xmm2xmm(0x50,0x66,tk_reg32);

				possiblecpu=9;

				break;

			case a_movnti:	//MOVNTI

				movxmm3(0xC3,0,tk_reg32);

				possiblecpu=9;

				break;

			case a_movq2dq:	//MOVQ2DQ

				nexttok();

				hnumber=itok.number;

				if(tok!=tk_xmmreg)xmmregexpected(1);

				nextexpecting2(tk_camma);

				if(tok!=tk_mmxreg)mmxregexpected(2);

				op(0xF3);

				outword(0xD60F);

				op(0xC0+hnumber+itok.number*8);

				possiblecpu=9;

				break;

			case a_movupd:

				movxmm(0x10,0x66);

				possiblecpu=9;

				break;

			case a_movups:

				movxmm(0x10,0);

				possiblecpu=8;

				break;

			case a_movss:

				movxmm(0x10,0xF3);

				possiblecpu=8;

				break;

			case a_movhps:

				movxmm2(0x16);

				possiblecpu=8;

				break;

			case a_movlps:

				movxmm2(0x12);

				possiblecpu=8;

				break;



			case -1: codeexpected(); break;

			default:

				preerror("sorry, this instruction is not supported");

				break;

		}

		asmparam=FALSE;

		if(cpu<possiblecpu)cpu=possiblecpu;

		if(next)nexttok();

	}

	else if(tok==tk_seg){

		switch((unsigned int)itok.number){

			case ES: op(0x26); break;

			case SS: op(0x36); break;

			case CS: op(0x2E); break;

			case DS: op(0x3E); break;

			case FS: op(0x64);

				if(cpu<3)cpu=3;

				break;

			case GS: op(0x65);

				if(cpu<3)cpu=3;

				break;

			default: beep(); break;

		}

		nextexpecting2(tk_colon);

	}

	else if(tok==tk_locallabel)define_locallabel();

	else if(tok==tk_at&&ScanTok3()==tk_colon){

		nexttok();

		LLabel();

	}

	else codeexpected();

	if(tok==tk_semicolon)nexttok();

}



void cmov(int num)

{

int type=r32;

int reg;

	nexttok();

	if(tok==tk_reg)type=r16;

	else if(tok!=tk_reg32)reg32regexpected(1);

	reg=itok.number;

	ClearReg(reg);

	nextexpecting2(tk_camma);

	op66(type);

	switch(tok){

		case tk_reg:

			if(type==r32)reg32expected(2);

			goto regs;

		case tk_reg32:

			if(type==r16)regexpected(2);

regs:

			op(0x0F);

			op(0x40+num);

			op(0xC0+reg*8+itok.number);

			break;

		case tk_wordvar:

		case tk_intvar:

			if(type==r32)dwordvalexpected();

			CheckAllMassiv(bufrm,2,&strinf);

			goto dwords;

		case tk_dwordvar:

		case tk_longvar:

			if(type==r16)wordvalexpected();

			CheckAllMassiv(bufrm,4,&strinf);

dwords:

			outseg(&itok,3);

			op(0x0F);

			op(0x40+num);

			op(itok.rm+reg*8);

			outaddress(&itok);

			break;

		default:

			varexpected(2);

			break;

	}

}



#ifdef OPTVARCONST

int GetOperand(int code)

{

	switch(code){

		case a_inc:	//INC

		case a_add: return tk_plus;

		case a_or: return tk_or;

		case a_and:	return tk_and;

		case a_dec:	//DEC

		case a_sub:	return tk_minus;

		case a_xor:	return tk_xor;

		case a_not:	return tk_not;

		case a_neg:	return tk_numsign;

		case a_shl:	return tk_ll;

		case a_shr:	return tk_rr;

	}

	return tokens;

}

#endif



void  asmtwo1(int basecode) // used for ADD ADC SUB SBB CMP AND OR XOR.

{

unsigned long holdnumber2;

int htok,typet=r16;

long longholdnumber;

char *hbuf;

ITOK hstok;

unsigned char next=1;

SINFO hstr;

#ifdef OPTVARCONST

int initconst=FALSE;

int operand=GetOperand(basecode/8);

#endif

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

int i=tok;

	switch(htok){

		case tk_reg:

			if((basecode/8)!=a_cmp)ClearReg(hstok.number);

		  switch(tok){

				case tk_undefofs:

					strcpy(hstok.name,itok.name);

					tok=tk_number;

					goto wnum;

				case tk_minus:

					if(tok2!=tk_number){

						wordvalexpected();

						break;

					}

				case tk_number:

wnum:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

					next=0;

					op66(r16);

					if(hstok.number==AX){

						op(4+1+basecode);

						if((postnumflag&f_reloc)!=0)AddReloc();

						if(i==tk_undefofs)AddUndefOff(2,hstok.name);

						outword(holdnumber2);

					}

					else{

						if((postnumflag&f_reloc)==0&&short_ok(holdnumber2)){

							op(128+2+1);

							op(128+64+hstok.number+basecode);

							op(holdnumber2);

						}

						else{

							op(128+1);

							op(128+64+hstok.number+basecode);

							if((postnumflag&f_reloc)!=0)AddReloc();

							if(i==tk_undefofs)AddUndefOff(2,hstok.name);

							outword(holdnumber2);

						}

					}

					break;

				case tk_postnumber:

					op66(r16);

					if(hstok.number==AX)op(4+1+basecode);

					else{

						op(128+1);

						op(128+64+hstok.number+basecode);

					}

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					outword((unsigned int)itok.number);

					break;

				case tk_reg:

					op66(r16);

					op(2+1+basecode);

					op(128+64+(unsigned int)itok.number+hstok.number*8);

					break;

				case tk_wordvar:

				case tk_intvar:

					CheckAllMassiv(bufrm,2,&strinf);

					op66(r16);

					outseg(&itok,2);

					op(2+1+basecode);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default: wordvalexpected(); break;

			}

			break;

		case tk_reg32:

			if((basecode/8)!=a_cmp)ClearReg(hstok.number);

			switch(tok){

				case tk_undefofs:

					strcpy(hstok.name,itok.name);

					tok=tk_number;

					goto dnum;

				case tk_minus:

					i=tk_number;

					if(tok2!=tk_number){

						dwordvalexpected();

						break;

					}

				case tk_number:

dnum:

					op66(r32);

					asmparam=FALSE;

					longholdnumber=doconstdwordmath();

					next=0;

					if(i==tk_number&&(postnumflag&f_reloc)==0&&short_ok(longholdnumber,TRUE)){

						op(128+2+1);

						op(128+64+hstok.number+basecode);

						op((int)longholdnumber);

					}

					else{

						if(hstok.number==EAX)op(4+1+basecode);

						else{

							op(128+1);

							op(128+64+hstok.number+basecode);

						}

						if((postnumflag&f_reloc)!=0)AddReloc();

						if(i==tk_undefofs)AddUndefOff(2,hstok.name);

						outdword(longholdnumber);

					}

					break;

				case tk_postnumber:

					op66(r32);

					if(hstok.number==EAX)op(4+1+basecode);

					else{

						op(128+1);

						op(128+64+hstok.number+basecode);

					}

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					outdword(itok.number);

					break;

				case tk_reg32:

					op66(r32);

					op(2+1+basecode);

					op(128+64+(unsigned int)itok.number+hstok.number*8);

					break;

				case tk_dwordvar:

				case tk_longvar:

					CheckAllMassiv(bufrm,4,&strinf);

					op66(r32);

					outseg(&itok,2);

					op(2+1+basecode);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default: dwordvalexpected(); break;

			}

			if(cpu<3)cpu=3;

			break;

		case tk_beg:

			if((basecode/8)!=a_cmp)ClearReg(hstok.number>3?hstok.number-4:hstok.number);

			switch(tok){

				case tk_minus:

					if(tok2!=tk_number){

						bytevalexpected(2);

						break;

					}

				case tk_number:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

					next=0;

					if(hstok.number==AL)op(4+basecode);

					else{

						op(128);

						op(128+64+hstok.number+basecode);

					}

					op(holdnumber2);

					break;

				case tk_beg:

					op(2+basecode);

					op(128+64+(unsigned int)itok.number+hstok.number*8);

					break;

				case tk_bytevar:

				case tk_charvar:

					CheckAllMassiv(bufrm,1,&strinf);

					outseg(&itok,2);

					op(2+basecode);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default: bytevalexpected(2); break;

			}

			break;

		case tk_dwordvar:

		case tk_longvar:

			typet=r32;

			if(cpu<3)cpu=3;

		case tk_intvar:

		case tk_wordvar:

			if((basecode/8)!=a_cmp)KillVar(hstok.name);

			CheckAllMassiv(hbuf,typet,&hstr,&hstok);

			op66(typet);

			outseg(&hstok,2);

			switch(tok){

				case tk_undefofs:

					strcpy(hstok.name,itok.name);

					tok=tk_number;

					goto vnum;

				case tk_minus:

					if(tok2!=tk_number)goto erval;

				case tk_number:

vnum:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

#ifdef OPTVARCONST

					if(i==tk_number&&(postnumflag&f_reloc)==0){

						initconst=UpdVarConst(&hstok,holdnumber2,tk_dword,operand);

					}

#endif

					next=0;

					if(i!=tk_undefofs&&(postnumflag&f_reloc)==0&&short_ok(holdnumber2,typet/2-1)){

						op(128+2+1);

						op(hstok.rm+basecode);

						outaddress(&hstok);

						op(holdnumber2);

					}

					else{

						op(128+1);

						op(hstok.rm+basecode);

						outaddress(&hstok);

						if((postnumflag&f_reloc)!=0)AddReloc();

						if(i==tk_undefofs)AddUndefOff(2,hstok.name);

						if(typet==r16)outword(holdnumber2);

						else outdword(holdnumber2);

					}

					break;

				case tk_postnumber:

					if(typet==r32)goto erval;

					op(128+1);

					op(hstok.rm+basecode);

					outaddress(&hstok);

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					if(typet==r16)outword(itok.number);

					else outdword(itok.number);

					break;

				case tk_reg32:

					if(typet==r16)goto erval;

				case tk_reg:

					op(1+basecode);

					op(hstok.rm+(unsigned int)itok.number*8);

					outaddress(&hstok);

					break;

				default:

erval:

					if(typet==r16)wordvalexpected();

					else dwordvalexpected();

					break;

			}

#ifdef OPTVARCONST

			if(initconst==FALSE)ClearVarByNum(&hstok);

#endif



			break;

		case tk_bytevar:

		case tk_charvar:

			if((basecode/8)!=a_cmp)KillVar(hstok.name);

			CheckAllMassiv(hbuf,1,&hstr,&hstok);

			switch(tok){

				case tk_minus:

					if(tok2!=tk_number){

						bytevalexpected(2);

						break;

					}

				case tk_number:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

#ifdef OPTVARCONST

					if((postnumflag&f_reloc)==0){

						initconst=UpdVarConst(&hstok,holdnumber2,tk_byte,operand);

					}

#endif

					next=0;

					outseg(&hstok,2);

					op(128);

					op(hstok.rm+basecode);

					outaddress(&hstok);

					op(holdnumber2);

					break;

				case tk_beg:

					outseg(&hstok,2);

					op(basecode);

					op(hstok.rm+(unsigned int)itok.number*8);

					outaddress(&hstok);

					break;

				default: bytevalexpected(2); break;

			}

#ifdef OPTVARCONST

			if(initconst==FALSE)ClearVarByNum(&hstok);

#endif

			break;

		default: varexpected(1);	break;

	}

	if(next)nexttok();

}



int GOTO()

{

unsigned char next=1;

	CheckIP();

#ifdef OPTVARCONST

	ClearLVIC();

#endif

	clearregstat();

	switch(tok){

		case tk_proc:

		case tk_interruptproc:

			if(itok.segm!=NOT_DYNAMIC){

				idrec *ptr=itok.rec;

				itok.segm=ptr->recsegm=DYNAMIC_USED;

				itok.rm=tok=tk_undefofs;	//ᬥ饭�� �� �� �����⭮� ��⪨

				goto undefproc;

			}

			jumploc(itok.number);	//�� ��楤��� ��� ࠭���

			break;

		case tk_number:

			asmparam=FALSE;

			jumploc(doconstlongmath());//�� ������� ����

			next=0;

			break;

		case tk_ID:

			addlocaljump(CALL_SHORT); //��������� �������� ����

			outword(0x00EB); 	// JMP SHORT

			break;

		case tk_id:

			tobedefined(CALL_SHORT,tk_void);//�������� ������� ����

			outword(0x00EB);	// JMP SHORT

			break;

		case tk_declare:

			tok=tk_undefproc;

			updatetree();

		case tk_locallabel:

		case tk_undefproc:		//��������� ���

undefproc:

			addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT));

			outword(0x00EB);	// JMP SHORT

			break;

		default: shortjumperror(); break;

	}

	return next;

}



unsigned char gotol(int faradd)

{

unsigned char next=1;

unsigned long hnumber;

unsigned int i=0;

	CheckIP();

#ifdef OPTVARCONST

	ClearLVIC();

#endif

	clearregstat();

	switch(tok){

		case tk_declare:

			if(tok2!=tk_openbracket){

				tok=tk_undefproc;

				updatetree();

			}

		case tk_locallabel:

		case tk_undefproc:

			if(tok2==tk_openbracket){

				asmparam=FALSE;

				if(doanyundefproc(TRUE)==tokens)next=0;

				break;

			}

			if(faradd==0){

				addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32)));

				jumploc0();

			} 			/* JMP num */

			else invalidfarjumpitem();

			break;

		case tk_proc:

			if(tok2==tk_openbracket){

				doanyproc(TRUE);

				break;

			}

			if(itok.segm!=NOT_DYNAMIC){

				idrec *ptr=itok.rec;

				itok.segm=ptr->recsegm=DYNAMIC_USED;

				itok.rm=tok=tk_undefofs;	//ᬥ饭�� �� �� �����⭮� ��⪨

		 		if(faradd==0){

					addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?JMP_NEAR:JMP_32)));

					jumploc0();

					break;

				} 			/* JMP num */

			}

		case tk_interruptproc:

			if(faradd==0)jumploc(itok.number);

			else invalidfarjumpitem();

			break;

		case tk_apiproc:

			asmparam=FALSE;

			if(tok2==tk_openbracket){

				if(doanyundefproc(TRUE)==tokens)next=0;

			}

			else{

				if(FastCallApi==TRUE){

					outword(0x25ff);

					AddApiToPost(itok.number);

				}

				else{

					addacall(itok.number,(unsigned char)CALL_32);

					jumploc0();

				}

			}

			break;

		case tk_minus:

			if(tok2!=tk_number)goto err;

		case tk_number:

			asmparam=FALSE;

			hnumber=doconstdwordmath();

			if(faradd==0)jumploc(hnumber);

			else{

				op(0xEA);

				expecting2(tk_colon);

				int htok=tok;

				char name[IDLENGTH];

				if(tok==tk_undefofs){

					tok=tk_number;

					strcpy(name,itok.name);

				}

				unsigned long tempi=doconstdwordmath();

				if(postnumflag&f_reloc)AddReloc();

				if(htok==tk_undefofs)AddUndefOff(2,name);

				if(am32==FALSE)outword((unsigned int)tempi);

				else outdword(tempi);

				outword((unsigned int)hnumber);

			}

			next=0;

			break;	 /* JMP num */

		case tk_postnumber:

			if(faradd==0){

				op(0xE9);

				(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

				if(am32==FALSE)outword((unsigned int)itok.number);

				else outdword(itok.number);

			}

			else invalidfarjumpitem();

			break;

		case tk_reg32:

			op66(r32);

			goto jmpreg;

		case tk_reg:

			op66(r16);

jmpreg:

			if(faradd==0){

				op(0xFF);

				op(0xE0+(unsigned int)itok.number);

			} 	 /* JMP reg */

			else invalidfarjumpitem();

			break;

		case tk_ID:

			if(faradd==0){

				addlocaljump(am32==FALSE?JMP_NEAR:JMP_32);

				jumploc0();

			} 		 /* JMP num */

			else invalidfarjumpitem();

			break;

		case tk_id:

			if(faradd==0){

				tobedefined(am32==FALSE?JMP_NEAR:JMP_32,tk_void);

				jumploc0();

			} 		 /* JMP num */

			else invalidfarjumpitem();

			break;

		case tk_dwordvar:

		case tk_longvar:

			i=2;

		case tk_intvar:

		case tk_wordvar:

			i+=2;

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,2);

			op(0xFF);  op(0x20+itok.rm+(faradd==0?(i==4&&am32==0?8:0):8));

			outaddress(&itok);

			break;

		default:

err:

			preerror("Invalid item for JMP");

			break;

	}

	return next;

}



void  asmregmem(int out1,int out2) // used for LEA LDS LES LFS LGS LSS.

{

int holdreg;

	nexttok();

	op66(tok==tk_reg?r16:r32);

	if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1);

	holdreg=(unsigned int)itok.number;

	ClearReg(itok.number);

	nextexpecting2(tk_camma);

	switch(tok){

		case tk_intvar:

		case tk_wordvar:

		case tk_charvar:

		case tk_bytevar:

		case tk_longvar:

		case tk_dwordvar:

			break;

		default: varexpected(2);

	}

	CheckAllMassiv(bufrm,2,&strinf);

	if(out2==0)outseg(&itok,2);

	else outseg(&itok,3);

	op(out1);

	if(out2!=0)op(out2);

	op(itok.rm+holdreg*8);

	outaddress(&itok);

}



void Scanbit(int basecode)

{

unsigned long hnumber;

int htok,typet=r16;

	nexttok();

	hnumber=itok.number;

	ClearReg(itok.number);

	htok=tok;

	nextexpecting2(tk_camma);

	switch(htok){

		case tk_reg32:

			typet=r32;

			if(tok==tk_reg||tok==tk_wordvar||tok==tk_intvar)goto erval;

		case tk_reg:

		  switch(tok){

				case tk_reg32:

					if(typet==r16)goto erval;

				case tk_reg:

					op66(typet);

					op(0xf);

					op(basecode);

					op(0xc0+(unsigned int)itok.number+hnumber*8);

					break;

				case tk_dwordvar:

				case tk_longvar:

					if(typet==r16)goto erval;

				case tk_wordvar:

				case tk_intvar:

					CheckAllMassiv(bufrm,typet,&strinf);

					op66(typet);

					outseg(&itok,3);

					op(0xf);

					op(basecode);

					op(itok.rm+hnumber*8);

					outaddress(&itok);

					break;

				default:

erval:

					if(typet==r16)wordvalexpected();

					else dwordvalexpected();

					break;

			}

			break;

		default: reg32regexpected(1);

	}

	if(cpu<3)cpu=3;

}



void CheckBit(int code)

{

unsigned long holdnumber2;

int htok;

ITOK hstok;

unsigned char next=1;

char *hbuf;

SINFO hstr;

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	switch(htok){

		case tk_reg32:

		case tk_reg:

			op66(htok==tk_reg?r16:r32);

			if(code)ClearReg(hstok.number);

		  switch(tok){

				case tk_number:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

					next=0;

					outword(0xba0f);

					op(0xe0+code+hstok.number);

					op(holdnumber2);

					break;

				case tk_reg32:

					if(tok!=htok){

						dwordvalexpected();

						break;

					}

				case tk_reg:

					if(tok!=htok)wordvalexpected();

					op(0xf);

					op(0xa3+code);

					op(0xc0+hstok.number+(unsigned int)itok.number*8);

					break;

				default: wordvalexpected(); break;

			}

			break;

		case tk_intvar:

		case tk_wordvar:

			CheckAllMassiv(hbuf,2,&hstr,&hstok);

			if(code)KillVar(hstok.name);

			op66(r16);

			switch(tok){

				case tk_number:

varc:

					asmparam=FALSE;

					holdnumber2=doconstlongmath();

					next=0;

					outseg(&hstok,3);

					outword(0xba0f);

					op(hstok.rm+code+0x20);

					outaddress(&hstok);

					op(holdnumber2);

					break;

				case tk_reg:

varreg:

					outseg(&hstok,3);

					op(0xf);

					op(0xa3+code);

					op(hstok.rm+(unsigned int)itok.number*8);

					outaddress(&hstok);

					break;

				default: wordvalexpected(); break;

			}

#ifdef OPTVARCONST

			if(code)ClearVarByNum(&hstok);

#endif

			break;

		case tk_dwordvar:

		case tk_longvar:

			CheckAllMassiv(hbuf,4,&hstr,&hstok);

			if(code)KillVar(hstok.name);

			op66(r32);

			if(tok==tk_number)goto varc;

			if(tok==tk_reg32)goto varreg;

			dwordvalexpected();

			break;

		default: varexpected(1);

	}

	if(cpu<3)cpu=3;

	if(next)nexttok();

}



void asmone1(int basecode)			 // used for INC and DEC.

{

int razr=r16;

#ifdef OPTVARCONST

int operand=GetOperand(basecode/8+a_inc);

#endif

	nexttok();

	switch(tok){

		case tk_reg32:

			if(cpu<3)cpu=3;

			razr=r32;

		case tk_reg:

			ClearReg(itok.number);

			op66(razr);

		  op(64+basecode+(unsigned int)itok.number);

			break;

		case tk_beg:

			ClearReg(itok.number);

			op(254); op(128+64+basecode+(unsigned int)itok.number);

			break;

		case tk_charvar:

		case tk_bytevar:

#ifdef OPTVARCONST

			UpdVarConst(&itok,1,tk_byte,operand);

#endif

			CheckAllMassiv(bufrm,1,&strinf);

			KillVar(itok.name);

			outseg(&itok,2);

			op(254);

			op(itok.rm+basecode);

			outaddress(&itok);

			break;

		case tk_longvar:

		case tk_dwordvar:

			CheckAllMassiv(bufrm,4,&strinf);

			if(cpu<3)cpu=3;

			razr=r32;

			goto dec;

		case tk_intvar:

		case tk_wordvar:

			CheckAllMassiv(bufrm,2,&strinf);

dec:

#ifdef OPTVARCONST

			UpdVarConst(&itok,1,tk_dword,operand);

#endif

			KillVar(itok.name);

			op66(razr);

			outseg(&itok,2);

			op(255);

			op(itok.rm+basecode);

			outaddress(&itok);

			break;

		default: varexpected(0);	break;

	}

}



void asmone2(int basecode)			 // used for NEG NOT MUL IMUL DIV IDIV.

{

int razr=r16;

#ifdef OPTVARCONST

int operand=GetOperand((basecode-16)/8+a_not);

#endif

	nexttok();

	switch(tok){

		case tk_reg32:

			if(cpu<3)cpu=3;

			razr=r32;

		case tk_reg:

			ClearReg(itok.number);

			op66(razr);

		  op(246+1); op(128+64+basecode+(unsigned int)itok.number); break;

		case tk_beg:

			ClearReg(itok.number);

			op(246); op(128+64+basecode+(unsigned int)itok.number); break;

			razr=r8;

		case tk_charvar:

		case tk_bytevar:

#ifdef OPTVARCONST

			UpdVarConst(&itok,0,tk_dword,operand);

#endif

			CheckAllMassiv(bufrm,1,&strinf);

			KillVar(itok.name);

			outseg(&itok,2);

			op(246);

			op(itok.rm+basecode);

			outaddress(&itok);

			razr=r8;

			break;

		case tk_longvar:

		case tk_dwordvar:

			CheckAllMassiv(bufrm,4,&strinf);

			if(cpu<3)cpu=3;

			razr=r32;

			goto neg;

		case tk_intvar:

		case tk_wordvar:

			CheckAllMassiv(bufrm,2,&strinf);

neg:

#ifdef OPTVARCONST

			UpdVarConst(&itok,0,tk_dword,operand);

#endif

			KillVar(itok.name);

			op66(razr);

			outseg(&itok,2);

			op(247);

			op(itok.rm+basecode);

			outaddress(&itok);

			break;

		default: varexpected(0);	break;

	}

	if(basecode!=16&&basecode!=24){

		ClearReg(AX);

		if(razr!=r8)ClearReg(DX);

	}

}



void  asmshortjump(int shortcode,int nearcode)

{

unsigned char next=1,shortjump=1;

unsigned int address;

#ifdef OPTVARCONST

	ClearLVIC();

#endif

	nexttok();

	if(stricmp("FAR",itok.name)==0){ 	 // case insensitive

		preerror("FAR jump not available for this instruction");

		nexttok();

	}

	else if(stricmp("NEAR",itok.name)==0){  // case insensitive

		shortjump=0;

		nexttok();

	}

	else if(stricmp("SHORT",itok.name)==0)nexttok();  // case insensitive

	if(shortjump){

		CheckIP();

		switch(tok){

			case tk_proc:

				*(unsigned int *)&itok.number-=outptr+2;

				if(short_ok(itok.number)){

					op(shortcode);

					op((unsigned int)itok.number);

				}

				else shortjumptoolarge();

				break;

			case tk_number:

				asmparam=FALSE;

				address=doconstdwordmath()-(outptr+2);

				if(short_ok(address)){

					op(shortcode);

					op(address);

				}

				else shortjumptoolarge();

				next=0;

				break;

			case tk_ID:

				addlocaljump(CALL_SHORT);

				op(shortcode); op(0x00);	 /* JXX SHORT */

				break;

			case tk_id:

				tobedefined(CALL_SHORT,tk_void);

				op(shortcode); op(0x00);	 /* JXX SHORT */

				break;

			case tk_declare:

				tok=tk_undefproc;

				updatetree();

			case tk_locallabel:

			case tk_undefproc:

				addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:CALL_SHORT));

				op(shortcode); op(0x00);		/* JXX SHORT */

				break;

			default: shortjumperror(); break;

		}

	}

	else if(nearcode!=0){

unsigned long numlong;

		asmparam=FALSE;

		switch(tok){

			case tk_proc:

				op(0xF); op(nearcode);

				numlong=itok.number-outptr-2;

				if(am32==FALSE)outword((unsigned int)numlong);

				else outdword(numlong-2);

				break;

			case tk_number:

				op(0xF); op(nearcode);

				numlong=doconstdwordmath()-outptr-2;

				if(am32==FALSE)outword((unsigned int)numlong);

				else outdword(numlong-2);

				next=0;

				break;

			case tk_undefofs:	// ???? 32 ���� ०��

				op(0xF); op(nearcode);

				AddUndefOff(2,itok.name);

				outword(-(int)(outptr-2));

				if(am32!=FALSE)outword(0x0000);

				break;

			case tk_postnumber:

				op(0xF); op(nearcode);

				(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

				numlong=itok.number-outptr-2;

				if(am32==FALSE)outword((unsigned int)numlong);

				else outdword(numlong-2);

				break;

			case tk_ID:

				op(0xF);	 // must go before tobedefined()

				addlocaljump(am32==FALSE?CALL_NEAR:CALL_32);

				op(nearcode); outword(0x0000);			/* JXX NEAR */

				if(am32!=FALSE)outword(0x0000);

				break;

			case tk_id:

				op(0xF);	 // must go before tobedefined()

				tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void);

				op(nearcode); outword(0x0000);			/* JXX NEAR */

				if(am32!=FALSE)outword(0x0000);

				break;

			case tk_declare:

				tok=tk_undefproc;

				updatetree();

			case tk_locallabel:

			case tk_undefproc:

				op(0xF);	 // must go before addacall()

				addacall((unsigned int)itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32==FALSE?CALL_NEAR:CALL_32)));

				op(nearcode); outword(0x0000);  /* JXX NEAR */

				if(am32!=FALSE)outword(0x0000);

				break;

			default: preerror("Invalid operand for NEAR jump"); break;

		}

		if(cpu<3)cpu=3;

	}

	else preerror("NEAR jump not available for this instruction");

	if(next)nexttok();

}



void lar_lsl(int code)

{

unsigned char possiblecpu=0;

int razr=r16;

	nexttok();

	if(tok!=tk_reg&&tok!=tk_reg32)reg32regexpected(1);

	int htok=tok;

	int hnumber=(unsigned int)itok.number;

	ClearReg(itok.number);

	nextexpecting2(tk_camma);

	switch(tok){

		case tk_reg32:

			if(htok==tk_reg)reg32expected(1);

			possiblecpu=3;

			razr=r32;

			goto lar;

		case tk_reg:

			if(htok==tk_reg32)regexpected(1);

			possiblecpu=2;

lar:

			op66(razr);

			op(0x0f);

			op(code);

			op(0xc0+(unsigned int)itok.number+hnumber*8);

			break;

		case tk_longvar:

		case tk_dwordvar:

			if(htok==tk_reg)reg32expected(1);

			CheckAllMassiv(bufrm,4,&strinf);

			possiblecpu=3;

			razr=r32;

			goto lar1;

		case tk_intvar:

		case tk_wordvar:

			if(htok==tk_reg32)regexpected(1);

			possiblecpu=2;

			CheckAllMassiv(bufrm,2,&strinf);

lar1:

			op66(razr);

			outseg(&itok,3);

			op(0x0f);

			op(code);

			op(itok.rm+hnumber*8);

			outaddress(&itok);

			break;

		default: invalidoperand(2); break;

	}

	if(possiblecpu>cpu)cpu=possiblecpu;

}



unsigned char tabldeckr(int code)

{

unsigned int i=0;

int htok;

unsigned char next=1;

char name[IDLENGTH];

	nexttok();

	htok=tok;

	KillVar(itok.name);

	switch(tok){

		case tk_longvar:

		case tk_dwordvar:

			i=2;

		case tk_intvar:

		case tk_wordvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			i++;

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,3);

			outword(0x010f);

			op(itok.rm+code);

			outaddress(&itok);

			break;

		case tk_undefofs:

			strcpy(name,itok.name);

			tok=tk_number;

		case tk_number:

			i=doconstdwordmath();

			outword(0x010f);

			op((am32==FALSE?rm_d16:rm_d32)+code);

		 	if(postnumflag&f_reloc)AddReloc();

		 	if(htok==tk_undefofs)AddUndefOff(2,name);

			if(am32)outdword(i);

			else outword(i);

			next=0;

			break;

		default: varexpected(0);

	}

	if(cpu<2)cpu=2;

	return next;

}



void  protectinstr(int code,int code2)

{

int i=0;

	nexttok();

	switch(tok){

		case tk_longvar:

		case tk_dwordvar:

			i=2;

		case tk_intvar:

		case tk_wordvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			i++;

#ifdef OPTVARCONST

			ClearVarByNum(&itok);

#endif

			CheckAllMassiv(bufrm,i,&strinf);

			KillVar(itok.name);

			outseg(&itok,3);

			op(0x0f);

			op(code);

			op(itok.rm+code2);

			outaddress(&itok);

			break;

		case tk_reg32:

		case tk_reg:

			ClearReg(itok.number);

			op(0x0f);

			op(code);

			op(0xc0+code2+(unsigned int)itok.number);

			break;

		default: wordvalexpected();

	}

	if(cpu<2)cpu=2;

}



void doasmmov() 		// do MOV

{

unsigned char next=1,possiblecpu=0;

int htok,typet;

ITOK hstok;

char *hbuf;

SINFO hstr;

#ifdef OPTVARCONST

int initconst=FALSE;

#endif

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	typet=r16;

int i=tok;

	switch(htok){

		case tk_reg32:

			possiblecpu=3;

			typet=r32;

		case tk_reg:

			switch(tok){

				case tk_debugreg:

					ClearReg(hstok.number);

					if(typet==r16)goto erreg;

					outword(0x210F);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					possiblecpu=4;

					if((unsigned int)itok.number<=DR3||(unsigned int)itok.number==DR6

					   ||(unsigned int)itok.number==DR7)possiblecpu=3;

					break;

				case tk_controlreg:

					ClearReg(hstok.number);

					if(typet==r16)goto erreg;

					outword(0x200F);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					possiblecpu=4;

					if((unsigned int)itok.number<=CR3)possiblecpu=3;

					break;

				case tk_testreg:

					ClearReg(hstok.number);

					if(typet==r16)goto erreg;

					outword(0x240F);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					possiblecpu=4;

					if((unsigned int)itok.number==TR6||(unsigned int)itok.number==TR7)possiblecpu=3;

					break;

				case tk_reg32:

					if(typet==r16)goto erreg;

				case tk_reg:

					RegToReg(hstok.number,itok.number,typet);

					op66(typet);

					op(0x89);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					break;

				case tk_undefofs:

					strcpy(hstok.name,itok.name);

					tok=tk_number;

					goto wnum;

				case tk_minus:

					if(tok2!=tk_number){

						wordvalexpected();

						break;

					}

				case tk_number:

wnum:

					op66(typet);

					op(0xB8+hstok.number);

					ClearReg(hstok.number);

					asmparam=FALSE;

					SaveNumber(typet,i,hstok.name);

					next=0;

					break;

				case tk_postnumber:

					ClearReg(hstok.number);

					op66(typet);

					op(0xB8+hstok.number);

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					if(typet==r32)outdword(itok.number);

					else outword((unsigned int)itok.number);

					break;

				case tk_dwordvar:

				case tk_longvar:

					if(typet==r16)goto erreg;

				case tk_wordvar:

				case tk_intvar:

					CheckAllMassiv(bufrm,typet,&strinf);

					IDZToReg(itok.name,hstok.number,typet);

					op66(typet);

					if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){

						outseg(&itok,1);

						op(0xA1);

					}

					else{

						outseg(&itok,2);

						op(0x8B);

						op(itok.rm+hstok.number*8);

					}

					outaddress(&itok);

					break;

				case tk_seg:

					if(typet==r32)goto erreg;

					IDZToReg(itok.name,hstok.number,typet);

					op66(r16);

					op(0x8C);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					if((unsigned int)itok.number==FS||(unsigned int)itok.number==GS)possiblecpu=3;

					break;

				default:

erreg:

					invalidoperand(2); break;

			}

			break;

		case tk_beg:

			ClearReg(hstok.number%4);

			switch(tok){

				case tk_beg:

						op(0x88);

						op(128+64+(unsigned int)itok.number*8+hstok.number);

					break;

				case tk_number:

					op(0xB0+hstok.number);

					asmparam=FALSE;

					op((int)doconstlongmath());

					next=0;

					break;

				case tk_bytevar:

				case tk_charvar:

					CheckAllMassiv(bufrm,1,&strinf);

					if(hstok.number==0&&((itok.rm==rm_d16&&itok.sib==CODE16)||(itok.rm==rm_d32&&(itok.sib==CODE32||itok.sib==0)))){

						outseg(&itok,1);

						op(0xA0);

					}

					else{

						outseg(&itok,2);

						op(0x8A);

						op(itok.rm+hstok.number*8);

					}

					outaddress(&itok);

					break;

				default: invalidoperand(2); break;

			}

			break;

		case tk_seg:

			if(hstok.number==CS){

				invalidoperand(1); break;

			}

			switch(tok){

				case tk_reg:

					op66(r16);

				  op(0x8E);

					op(128+64+hstok.number*8+(unsigned int)itok.number);

					if(hstok.number==FS||hstok.number==GS)possiblecpu=3;

					break;

				case tk_wordvar:

				case tk_intvar:

					CheckAllMassiv(bufrm,2,&strinf);

					op66(r16);

					outseg(&itok,2);

					op(0x8E);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					if(hstok.number==FS||hstok.number==GS)possiblecpu=3;

					break;

				default: invalidoperand(2); break;

			}

			break;

		case tk_dwordvar:

		case tk_longvar:

			possiblecpu=3;

			typet=r32;

		case tk_wordvar:

		case tk_intvar:

			KillVar(itok.name);

			CheckAllMassiv(hbuf,typet,&hstr,&hstok);

			op66(typet);

			switch(tok){

				case tk_reg32:

					if(typet==r16)goto ervar;

				case tk_reg:

			/*if((tok==tk_reg||tok==tk_reg32)&&hbuf==NULL&&hstr.bufstr==NULL)*/

					AddRegVar(itok.number,typet,&hstok);

					if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){

						outseg(&hstok,1);

						op(0xA3);

						outaddress(&hstok);

					}

					else{

						outseg(&hstok,2);

						op(0x89);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

					}

					break;

				case tk_undefofs:

					strcpy(hstok.name,itok.name);

					tok=tk_number;

					goto vnum;

				case tk_minus:

					if(tok2!=tk_number){

						wordvalexpected();

						break;

					}

				case tk_number:

vnum:

					outseg(&hstok,2);

					op(0xC7);

					op(hstok.rm);

					outaddress(&hstok);

					asmparam=FALSE;

#ifdef OPTVARCONST

					unsigned long t;

					t=SaveNumber(typet,i,hstok.name);

					if(typet==r16)t&=0xffff;

					else t&=0xffffffff;

					if((i==tk_number||i==tk_minus)&&(postnumflag&f_reloc)){

						Const2Var(&hstok,t,tk_dword);

						initconst=TRUE;

					}

#else

					SaveNumber(typet,i,hstok.name);

#endif

					next=0;

					break;

				case tk_postnumber:

					outseg(&hstok,2);

					op(0xC7);

					op(hstok.rm);

					outaddress(&hstok);

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					if(typet==r16)outword((unsigned int)itok.number);

					else outdword(itok.number);

					break;

				case tk_seg:

					outseg(&hstok,2);

					if(typet==r32)goto ervar;

					op(0x8C);

					op(hstok.rm+(unsigned int)itok.number*8);

					outaddress(&hstok);

					if(hstok.number==FS||hstok.number==GS)possiblecpu=3;

					break;

				default:

ervar:

					invalidoperand(2); break;

			}

#ifdef OPTVARCONST

			if(initconst==FALSE)ClearVarByNum(&hstok);

#endif

			break;

		case tk_charvar:

		case tk_bytevar:

			KillVar(itok.name);

			CheckAllMassiv(hbuf,1,&hstr,&hstok);

			switch(tok){

				case tk_beg:

			/*if(tok==tk_beg&&hbuf==NULL&&hstr.bufstr==NULL)*/

					AddRegVar(itok.number,r8,&hstok);

					if(itok.number==0&&((hstok.rm==rm_d16&&hstok.sib==CODE16)||(hstok.rm==rm_d32&&(hstok.sib==CODE32||hstok.sib==0)))){

						outseg(&hstok,1);

						op(0xA2);

						outaddress(&hstok);

					}

					else{

						outseg(&hstok,2);

						op(0x88);

						op(hstok.rm+(unsigned int)itok.number*8);

						outaddress(&hstok);

					}

					break;

				case tk_number:

					outseg(&hstok,2);

					op(0xC6);

					op(hstok.rm);

					outaddress(&hstok);

					asmparam=FALSE;

#ifdef OPTVARCONST

					long t;

					t=doconstlongmath()&0xff;

					op(t);

					if((postnumflag&f_reloc)){

						initconst=TRUE;

						Const2Var(&hstok,t,tk_byte);

					}

#else

					op((int)doconstlongmath());

#endif

					next=0;

					break;

				default: invalidoperand(2); break;

			}

#ifdef OPTVARCONST

			if(initconst==FALSE)ClearVarByNum(&hstok);

#endif

			break;

		case tk_debugreg:

			if(tok==tk_reg32){

				outword(0x230F);

				op(128+64+hstok.number*8+(unsigned int)itok.number);

				possiblecpu=4;

				if(hstok.number<=DR3||hstok.number==DR6||hstok.number==DR7)possiblecpu=3;

			}

			else invalidoperand(2);

			break;

		case tk_controlreg:

			if(tok==tk_reg32){

				outword(0x220F);

				op(128+64+hstok.number*8+(unsigned int)itok.number);

				possiblecpu=4;

				if(hstok.number<=CR3)possiblecpu=3;

			}

			else invalidoperand(2);

			break;

		case tk_testreg:

			if(tok==tk_reg32){

				outword(0x260F);

				op(128+64+hstok.number*8+(unsigned int)itok.number);

				possiblecpu=4;

				if(hstok.number==TR6||hstok.number==TR7)possiblecpu=3;

			}

			else invalidoperand(2);

			break;

		default: invalidoperand(1); break;

	}

	asmparam=FALSE;

	if(possiblecpu>cpu)cpu=possiblecpu;

	if(next)nexttok();

}



void asmextend(int basecode)	 // procedure MOVSX and MOVZX

{

int regnum;

int razr=r16;

	nexttok();

	if(tok==tk_reg32)razr=r32;

	if(tok!=tk_reg32&&tok!=tk_reg)reg32regexpected(1);

	regnum=(unsigned int)itok.number*8;

	ClearReg(itok.number);

	nextexpecting2(tk_camma);

	switch(tok){

		case tk_reg:

			op66(razr);

			op(0xF); op(basecode|1);

			op(128+64+regnum+(unsigned int)itok.number);

			break;

		case tk_beg:

			op66(razr);

			op(0xF); op(basecode);

			op(128+64+regnum+(unsigned int)itok.number);

			break;

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(bufrm,2,&strinf);

			op66(razr);

			outseg(&itok,3);

			op(0xF); op(basecode|1);

			op(itok.rm+regnum);

			outaddress(&itok);

			break;

		case tk_bytevar:

		case tk_charvar:

			CheckAllMassiv(bufrm,1,&strinf);

			op66(razr);

			outseg(&itok,3);

			op(0xF); op(basecode);

			op(itok.rm+regnum);

			outaddress(&itok);

			break;

		default: varexpected(2); break;

	}

	if(cpu<3)cpu=3;

}



void movd()

{

ITOK hstok;

int htok;

char *hbuf;

SINFO hstr;

int i=0;

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok==tk_xmmreg)i++;

	switch(htok){

		case tk_reg32:

			ClearReg(hstok.number);

			if(tok==tk_mmxreg||i){	//MOVD EAX,MM0

				if(i)op(0x66);

				outword(0x7E0F);

				op(0xc0+hstok.number+(unsigned int)itok.number*8);

			}

			else mmxregexpected(2);

			break;

		case tk_dwordvar:

		case tk_longvar:

			if(tok==tk_mmxreg||i){	//MOVD mem,MM0

#ifdef OPTVARCONST

				ClearVarByNum(&hstok);

#endif

				CheckAllMassiv(hbuf,4,&hstr,&hstok);

				KillVar(hstok.name);

				outseg(&hstok,i==0?3:4);

				if(i)op(0x66);

				outword(0x7E0F);

				op(hstok.rm+(unsigned int)itok.number*8);

				outaddress(&hstok);

			}

			else mmxregexpected(2);

			break;

		case tk_xmmreg:

			i++;

		case tk_mmxreg:

			switch(tok){

				case tk_reg32:	//MOVD MM0,EAX

					if(i)op(0x66);

					outword(0x6E0F);

					op(0xc0+hstok.number*8+(unsigned int)itok.number);

					break;

				case tk_dwordvar:	//MOVD MMO,mem

				case tk_longvar:

					CheckAllMassiv(bufrm,4,&strinf);

					outseg(&itok,i==0?3:4);

					if(i)op(0x66);

					outword(0x6E0F);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default: dwordvalexpected();

			}

			break;

		default: mmxregordwordexpected(1);

	}

	if(cpu<6)cpu=6;

	if(i&&cpu<9)cpu=9;

}



void movq()

{

int htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

int i=1,xmm=0;

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok==tk_xmmreg)xmm++;

	switch(htok){

		case tk_qwordvar:

		case tk_doublevar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			if(tok==tk_mmxreg||xmm){	//MOVQ mem,MM0

#ifdef OPTVARCONST

				ClearVarByNum(&hstok);

#endif

				KillVar(hstok.name);

				CheckAllMassiv(hbuf,i,&hstr,&hstok);

				outseg(&hstok,xmm==0?3:4);

				if(xmm){

					op(0x66);

					outword(0xD60f);

				}

				else outword(0x7F0F);

				op(hstok.rm+(unsigned int)itok.number*8);

				outaddress(&hstok);

			}

			else mmxregexpected(2);

			break;

		case tk_mmxreg:

			switch(tok){

				case tk_mmxreg:	//MOVQ MM0,MM1

					outword(0x6F0F);

					op(0xc0+hstok.number*8+(unsigned int)itok.number);

					break;

				case tk_qwordvar:

				case tk_doublevar:

					i+=4;

				case tk_longvar:

				case tk_dwordvar:

				case tk_floatvar:

					i+=2;

				case tk_wordvar:

				case tk_intvar:

					i++;

				case tk_charvar:

				case tk_bytevar:

					CheckAllMassiv(bufrm,i,&strinf);

					outseg(&itok,3);

					outword(0x6F0F);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default: mmxregordwordexpected(2);

			}

			break;

		case tk_xmmreg:

			switch(tok){

				case tk_xmmreg:

					op(0xF3);

					outword(0x7e0F);

					op(0xc0+hstok.number*8+(unsigned int)itok.number);

					break;

				case tk_qwordvar:

				case tk_doublevar:

					i+=4;

				case tk_longvar:

				case tk_dwordvar:

				case tk_floatvar:

					i+=2;

				case tk_wordvar:

				case tk_intvar:

					i++;

				case tk_charvar:

				case tk_bytevar:

					CheckAllMassiv(bufrm,i,&strinf);

					outseg(&itok,4);

					op(0xF3);

					outword(0x7E0F);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					xmm++;

					break;

				default: xmmregorvarexpected(2);

			}

			break;

		default: mmxregordwordexpected(1);

	}

	if(cpu<6)cpu=6;

	if(xmm&&cpu<9)cpu=9;

}



void packMMX(int code,int code1,int code2)

{

unsigned int hnumber;

int htok,next=TRUE;

int i=1;

int xmm=FALSE;

	nexttok();

	hnumber=(unsigned int)itok.number;

	htok=tok;

	nextexpecting2(tk_camma);

	if(htok==tk_xmmreg)xmm=TRUE;

	else if(htok!=tk_mmxreg)mmxregexpected(1);

	switch(tok){

		case tk_mmxreg:

			if(xmm)xmmregexpected(2);

			op(0x0f);

			op(code);

			op(0xc0+hnumber*8+(unsigned int)itok.number);

			break;

		case tk_xmmreg:

			if(!xmm)mmxregexpected(2);

			else op(0x66);

			op(0x0f);

			op(code);

			op(0xc0+hnumber*8+(unsigned int)itok.number);

			break;

		case tk_number:

			if(xmm)op(0x66);

			op(0x0f);

			op(code1);

			op(code2+hnumber);

		 	asmparam=FALSE;

			op((unsigned int)doconstlongmath());

			next=FALSE;

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,xmm==FALSE?3:4);

			if(xmm)op(0x66);

			op(0x0f);

			op(code);

			op(itok.rm+hnumber*8);

			outaddress(&itok);

			break;

		default:

			mmxregordwordexpected(2);

			break;

	}

	if(cpu<6)cpu=6;

	if(xmm&&cpu<9)cpu=9;

	if(next==TRUE)nexttok();

}



void asmshift(int basecode) 		 // used for ROL ROR RCL RCR SHL SAL SHR SAR.

{

int htok,precode;

unsigned char holdbyte;

int usenumsh=TRUE;

ITOK hstok;

char *hbuf;

char next=1;

SINFO hstr;

int razr=r16;

#ifdef OPTVARCONST

int operand=GetOperand(basecode/8+a_rol);

#endif

	nexttok();

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok==tk_beg&&(unsigned int)itok.number==CL){

		precode=0xD2;

		usenumsh=FALSE;

	}

	else if(tok==tk_number){

		asmparam=FALSE;

		holdbyte=(unsigned char)doconstlongmath();

		if(holdbyte==1){

			precode=0xD0;

			usenumsh=FALSE;

		}

		else /*if(holdbyte!=0)*/{

			precode=0xC0;

			if(cpu<2)cpu=2;

		}

		next=0;

	}

	else clornumberexpected();

//	if(precode!=0){

		switch(htok){

			case tk_reg32:

				if(cpu<3)cpu=3;

				razr=r32;

			case tk_reg:

				ClearReg(hstok.number);

				op66(razr);

			  op(precode+1); op(128+64+basecode+hstok.number);

				break;

			case tk_beg:

				ClearReg(hstok.number);

				op(precode); op(128+64+basecode+hstok.number);

				break;

			case tk_charvar:

			case tk_bytevar:

#ifdef OPTVARCONST

				if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand);

				else ClearVarByNum(&hstok);

#endif

				CheckAllMassiv(hbuf,1,&hstr,&hstok);

				KillVar(hstok.name);

				outseg(&hstok,2);

				op(precode);

				op(hstok.rm+basecode);

				outaddress(&hstok);

				break;

			case tk_dwordvar:

			case tk_longvar:

				CheckAllMassiv(hbuf,4,&hstr,&hstok);

				if(cpu<3)cpu=3;

				razr=r32;

				goto rol;

			case tk_wordvar:

			case tk_intvar:

				CheckAllMassiv(hbuf,2,&hstr,&hstok);

rol:

#ifdef OPTVARCONST

				if(precode==0xD0||precode==0xc0)UpdVarConst(&hstok,holdbyte,tk_byte,operand);

				else ClearVarByNum(&hstok);

#endif

				KillVar(hstok.name);

				op66(razr);

				outseg(&hstok,2);

				op(precode+1);

				op(hstok.rm+basecode);

				outaddress(&hstok);

				break;

			default: varexpected(1); break;

		}

		if(usenumsh)op(holdbyte);

	if(next)nexttok();

}



void CheckCl(int code)

{

	op(0xf);

	if(tok==tk_beg){

		if(itok.number==CL)code++;

		else clornumberexpected();

	}

	else if(tok!=tk_number)clornumberexpected();

	op(code);

}



void Shxd(int code)

{

unsigned int h2number;

int htok,h2tok;

ITOK hstok;

char *hbuf;

unsigned char next=1;

SINFO hstr;

	nexttok();

	hstok=itok;

	htok=tok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	h2number=(unsigned int)itok.number;

	ClearReg(itok.number);

	h2tok=tok;

	nextexpecting2(tk_camma);

	switch(htok){

		case tk_reg:

			if(h2tok==tk_reg){

				op66(r16);

regreg:

				ClearReg(hstok.number);

				CheckCl(code);

				op(0xc0+hstok.number+(unsigned int)h2number*8);

				if(tok==tk_number){

					asmparam=FALSE;

					op(doconstlongmath());

					next=0;

				}

			}

			else regexpected(2);

			break;

		case tk_reg32:

			if(h2tok==tk_reg32){

				op66(r32);

				goto regreg;

			}

			else reg32expected(2);

			break;

		case tk_intvar:

		case tk_wordvar:

			if(h2tok==tk_reg){

				CheckAllMassiv(hbuf,2,&hstr,&hstok);

				op66(r16);

varreg:

#ifdef OPTVARCONST

			ClearVarByNum(&hstok);

#endif



			KillVar(hstok.name);

				outseg(&hstok,3);

				CheckCl(code);

				op(hstok.rm+h2number*8);

				outaddress(&hstok);

				if(tok==tk_number){

					asmparam=FALSE;

					op(doconstlongmath());

					next=0;

				}

			}

			else regexpected(2);

			break;

		case tk_dwordvar:

		case tk_longvar:

			if(h2tok==tk_reg32){

				CheckAllMassiv(hbuf,4,&hstr,&hstok);

				op66(r32);

				goto varreg;

			}

			else reg32expected(2);

			break;

		default: valueexpected();

	}

	if(cpu<3)cpu=3;

	if(next)nexttok();

}



void FpuType1(unsigned int addrm)

{

int opcode=0xd8;

int oscan=scanlexmode;

	scanlexmode=ASMLEX;

	nexttok();

	retoldscanmode(oscan);

	if(tok==tk_endline||tok==tk_semicolon){

		op(0xD8);

		op(0xC1+addrm);

		return;

	}

	if(tok==tk_double){

		opcode=0xdc;

		nexttok();

	}

	switch(tok){

		case tk_fpust:

			op(0xD8);

			op(0xC0+(unsigned int)itok.number+addrm);

			break;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			CheckAllMassiv(bufrm,4,&strinf);

			outseg(&itok,2);

			op(opcode);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		case tk_doublevar:

			CheckAllMassiv(bufrm,8,&strinf);

			outseg(&itok,2);

			op(0xDC);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		default: fpuvarexpected(0);

	}

}



void FpuType2(unsigned int addrm,unsigned int addrm2)

{

long hnum;

int opcode=0xd8;

int oscan=scanlexmode;

	scanlexmode=ASMLEX;

	nexttok();

	retoldscanmode(oscan);

	if(tok==tk_endline||tok==tk_semicolon){

		op(0xDE);

		op(0xC1+addrm);

		return;

	}

	if(tok==tk_double){

		opcode=0xdc;

		nexttok();

	}

	switch(tok){

		case tk_fpust:

			hnum=itok.number;

			nextexpecting2(tk_camma);

			if(hnum==0){

				if(tok==tk_fpust){

					op(0xD8);

					op(0xC0+addrm2+(unsigned int)itok.number);

				}

				else fpustakexpected(2);

			}

			else{

				if(tok==tk_fpust){

					if(itok.number!=0)fpu0expected();

					op(0xDC);

					op(0xC0+(unsigned int)hnum+addrm);

				}

				else fpustakexpected(2);

			}

			break;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			CheckAllMassiv(bufrm,4,&strinf);

			outseg(&itok,2);

			op(opcode);

			op(addrm2+itok.rm);

			outaddress(&itok);

			break;

		case tk_doublevar:

			CheckAllMassiv(bufrm,8,&strinf);

			outseg(&itok,2);

			op(0xDC);

			op(addrm2+itok.rm);

			outaddress(&itok);

			break;

		default: fpuvarexpected(1);

	}

}



void FpuType3(unsigned int opcode,unsigned int addrm)

{

int oscan=scanlexmode;



	scanlexmode=ASMLEX;

	nexttok();

//	scanlexmode=oscan;

	retoldscanmode(oscan);

	if((tok==tk_endline||tok==tk_semicolon)&&opcode!=0xDD){

		op(opcode);

		op(0xC1+addrm);

	}

	else if(tok==tk_fpust){

		op(opcode);

		op(0xC0+(unsigned int)itok.number+addrm);

	}

	else fpustakexpected(1);

	if(opcode==0xDE&&tok2==tk_camma){

		nexttok();

		nexttok();

		if(tok!=tk_fpust||itok.number!=0)fpu0expected();



	}

}



void FpuType4(unsigned int opcode,unsigned int addrm)

{

	nexttok();

	if(opcode==1&&(addrm==0x18||addrm==0)&&tok==tk_qwordvar){

		if(addrm==0)addrm=0x28;

		else addrm=0x38;

		CheckAllMassiv(bufrm,8,&strinf);

		KillVar(itok.name);

		outseg(&itok,2);

		op(0xDF);

		op(itok.rm+addrm);

		outaddress(&itok);

		return;

	}

	switch(tok){

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(bufrm,2,&strinf);

			KillVar(itok.name);

			outseg(&itok,2);

			op(0xDE + opcode);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			CheckAllMassiv(bufrm,4,&strinf);

			KillVar(itok.name);

			outseg(&itok,2);

			op(0xDA+opcode);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		default: fpuvarexpected(0);

	}

}



void  FpuType5(unsigned int opcode,unsigned int addrm)

{

int opc=0xd9;

int i=4;

	nexttok();

	if(tok==tk_qword||tok==tk_double){

		nexttok();

		tok=tk_qwordvar;

	}

	else if((strcmp(itok.name,"tbyte")==0||strcmp(itok.name,"ldouble")==0)&&addrm!=0x10){

		opc=0xdb;

		i=10;

		if(addrm==0)addrm=40;

		else addrm=56;

		nexttok();

		if(tok>=tk_charvar&&tok<=tk_wordvar)tok=tk_dwordvar;

	}

	switch(tok){

		case tk_fpust:

			op(opcode);

			op(0xC0+(unsigned int)itok.number+addrm);

			break;

		case tk_qwordvar:

		case tk_doublevar:

			opc=0xdd;

			i=8;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			CheckAllMassiv(bufrm,i,&strinf);

			if(opcode!=0xD9)KillVar(itok.name);

			outseg(&itok,2);

			op(opc);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		default: fpuvarexpected(0);

	}

}



void FpuType6(unsigned int opcode,unsigned int addrm)

{

int i=0;

	nexttok();

	if(opcode==0xDF){

		if(tok==tk_qword){

			nexttok();

			tok=tk_qwordvar;

		}

		if(strcmp(itok.name,"tbyte")==0){

			i=2;

			nexttok();

			tok=tk_qwordvar;

		}

	}

	switch(tok){

		case tk_qwordvar:

		if(opcode!=0xDF)wordvalexpected();

			i=+4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i+=2;

			CheckAllMassiv(bufrm,i,&strinf);

			KillVar(itok.name);

			outseg(&itok,2);

			op(opcode);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		default: wordvalexpected();

	}

}



void FpuType7(unsigned int addrm)

{

	nexttok();

	switch(tok){

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(bufrm,2,&strinf);

			if(addrm!=0x28)KillVar(itok.name);

			outseg(&itok,2);

			op(0xD9);

			op(itok.rm+addrm);

			outaddress(&itok);

			break;

		default: wordvalexpected();

	}

}



void FpuType8(unsigned int opcode,unsigned int addrm)

{

	nexttok();

	if(tok==tk_fpust&&itok.number==0&&tok2==tk_camma){

		nexttok();

		nexttok();

	}

	if(tok==tk_fpust){

		op(opcode);

		op(0xC0+(unsigned int)itok.number+addrm);

		if(cpu<7)cpu=7;

	}

	else fpustakexpected(1);

}



/* ***************** start of some quick codes ****************** */



int  short_ok(long thenumber,int reg32)

{

	if(reg32==TRUE){

		if(thenumber<=SHORTMAX&&thenumber>=SHORTMIN)return(1);

	}

	else{

		if((short)thenumber<=SHORTMAX&&(short)thenumber>=SHORTMIN)return(1);

	}

	return(0);

}



void cbw()

{

	if(optimizespeed&&(chip==5||chip==6)){

		outdword(0xFCC0C488);	//mov ah,al	sar AH,7

		op(7);

	}

	else{

		op66(r16);

		op(0x98);

	}

	ClearReg(AX);

}



void stosb()

{

	op(0xAA);

	ClearReg(DI);

}



void stosw()

{

	op66(r16);

	op(0xAB);

	ClearReg(DI);

}



void stosd()

{

	op66(r32);

	op(0xAB);

	if(cpu<3)cpu=3;

	ClearReg(DI);

}



void movsb()

{

	op(0xA4);

	ClearReg(DI);

	ClearReg(SI);

}



void movsw()

{

	op66(r16);

	op(0xA5);

	ClearReg(DI);

	ClearReg(SI);

}



void movsd()

{

	op66(r32);

	op(0xA5);

	if(cpu<3)cpu=3;

	ClearReg(DI);

	ClearReg(SI);

}



void pushds()  /* produce PUSH DS */

{

	RestoreStack();

	op(0x1E);

}



void pushss()

{

	RestoreStack();

	op(0x16);			/* PUSH SS */

}



void popes()	 /* produce POP ES */

{

	RestoreStack();

	op(0x07);

}



void ret()		/* produce RET */

{

	RestoreStack();

	op(0xC3);

}



void retf() 	/* produce RETF */

{

	RestoreStack();

	op(0xCB);

}



void jumploc(long loc)		 /* produce JUMP # */

{



	loc=loc-outptr-3;

	if(loc>-130&&loc<127){

		loc++;

		op(0xEB);

		op(loc);

		if(loc==0)notunreach=TRUE;

	}

	else{

		if(am32==FALSE){

			op(0xE9);

			outword(loc);

		}

		else{

			if(!optimizespeed&&(loc>126&&loc<65533)){

				outword(0xE966);

				outword(loc-1);

			}

			else{

				op(0xE9);

				outdword(loc-2);

			}

		}

	}

}



void callloc(long loc)	 /* produce CALL # */

{

	loc=loc-outptr-3;

	op(0xE8);

	if(am32==FALSE)	outword(loc);

	else outdword(loc-2);

}



void xorAHAH()	 /* produce XOR AH,AH */

{

	outword(0xE430);

	ConstToReg(0,AH,r8);

}



void xorAXAX()	 /* produce XOR AX,AX */

{

	op66(r16);

	outword(0xC031);

	ConstToReg(0,AX,r16);

}



void xorEAXEAX()	 /* produce XOR EAX,EAX */

{

	op66(r32);

	outword(0xC031);

	if(cpu<3)cpu=3;

	ConstToReg(0,AX,r32);

}



void ZeroReg(int reg, int razr)

{

	op66(razr);

	op(0x31);

	op(0xc0+9*reg);	//xor reg,reg

	ConstToReg(0,reg,razr);

}



void fwait()

{

	op(0x9B);

}



void cwdq(int razr)

{

	op66(razr);

	if(optimizespeed&&(chip==5||chip==6)){

		outword(0xC289);	//mov dx,ax

		op66(razr);

		outword(0xFAC1);	//sar dx,15

		op(razr==r16?15:31);

	}

	else op(0x99);

	ClearReg(DX);

}



void  nextexpecting2(int want)

{

	nexttok();

	expecting2(want);

}



void expecting2(int want)

{

	if(want!=tok)SwTok(want);

	nexttok();

}



void CheckIP()

{

	if(tok==tk_dollar){

		tok=tk_number;

		itok.number=outptr;

	}

}



void jumploc0()

{

	op(0xE9);

	outword(0); 	/* the large jump */

	if(am32!=FALSE)outword(0);

}



void callloc0()

{

	op(0xE8);

	outword(0);

	if(am32!=FALSE)outword(0);

}



void Leave()

{

	if((optimizespeed&&chip>3&&chip<7)||chip==0){

		outword(0xEC89);	// MOV SP,BP

		op(0x5D);

	}

	else op(0xC9);

}



void  tobedefined(int callkind,int expectedreturn)

{

//	strcpy(itok.name,(char *)string);

	string[0]=0;

	itok.flag=(unsigned char)(tok==tk_ID?tp_fastcall:(comfile==file_w32?tp_stdcall:tp_pascal));

	tok=tk_undefproc;

	itok.number=secondcallnum;

	itok.segm=NOT_DYNAMIC;

	itok.rm=expectedreturn;

	itok.post=0;

	addtotree(itok.name);

	addacall(secondcallnum++,(unsigned char)callkind);

}



void  addlocaljump(int callkind)

{

	addlocalvar((char *)string,tk_locallabel,secondcallnum,TRUE);

	addacall(secondcallnum++,(char)callkind);

}



unsigned long SaveNumber(int type,int tok4,char *name)

{

	unsigned long t=doconstdwordmath();

	if(tok4==tk_undefofs)AddUndefOff(0,name);

	else if((postnumflag&f_reloc)!=0)AddReloc();

	if(type==r16)outword((unsigned int)t);

	else outdword(t);

	return t;

}



void Swap2tok(int *tok4, ITOK *itok4, char **buf4, SINFO *strinf4, int *tok6,

	 ITOK *itok6, char **buf6, SINFO *strinf6)

{

int htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

	htok=*tok4;

	*tok4=*tok6;

	*tok6=htok;

	hstok=*itok4;

	*itok4=*itok6;

	*itok6=hstok;

	hbuf=*buf4;

	*buf4=*buf6;

	*buf6=hbuf;

	hstr=*strinf4;

	*strinf4=*strinf6;

	*strinf6=hstr;

}



int iTest(int mode)

{

int htok,i;

ITOK hstok;

char *hbuf;

SINFO hstr;

unsigned char possiblecpu=0,next=1;

unsigned long num;

 	asmparam=TRUE;

	nexttok();

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	if(tok==tk_number)hstok.number=doconstlongmath();

	else nexttok();

	expecting2(tk_camma);

	i=r16;

//	printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n",

//	 tok,itok.number,bufrm,htok,hstok.number,hbuf);

	if(htok==tk_number||htok==tk_postnumber)Swap2tok(&tok,&itok,&bufrm,&strinf,

			&htok,&hstok,&hbuf,&hstr);

//	printf("tok=%d itok.number=%u bufrm=%s htok=%d hstok.number=%u nbuf=%s\n",

//	 tok,itok.number,bufrm,htok,hstok.number,hbuf);

	switch(htok){

		case tk_reg32:

			i=r32;

			possiblecpu=3;

		case tk_reg:

			switch(tok){

				case tk_reg32:

					if(i==r16){

						reg32expected(1);

						return FALSE;

					}

					op66(i);

					op(0x85);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					break;

				case tk_reg:

					if(i==r32){

						reg32expected(2);

						return FALSE;

					}

					op66(i);

					op(0x85);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					break;

				case tk_number:

				 	asmparam=FALSE;

					num=doconstdwordmath();

					if(mode){

						if(num<256&&hstok.number<4)goto testal;

						if(num<65536)i=r16;

					}

					op66(i);

					if(hstok.number==AX)op(0xA9);

					else{

						op(0xF7);

						op(128+64+hstok.number);

					}

					if(i==r16)outword((unsigned int)num);

					else outdword(num);

					next=0;

					break;

				case tk_postnumber:

					if(i==r32)return FALSE;

					op66(r16);

					if(hstok.number==AX)op(0xA9);

					else{

						op(0xF7);

						op(128+64+hstok.number);

					}

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					outword(itok.number);	//�뫮 0

					break;

				case tk_dwordvar:

				case tk_longvar:

					if(i==r16){

						reg32expected(1);

						return FALSE;

					}

					CheckAllMassiv(bufrm,i,&strinf);

					op66(i);

					outseg(&itok,2);

					op(0x85);

					op(hstok.number*8+itok.rm);

					outaddress(&itok);

					break;

				case tk_wordvar:

				case tk_intvar:

					if(i==r32){

						regexpected(1);

						return FALSE;

					}

					CheckAllMassiv(bufrm,i,&strinf);

					op66(i);

					outseg(&itok,2);

					op(0x85);

					op(hstok.number*8+itok.rm);

					outaddress(&itok);

					break;

				default: return FALSE;

			}

			break;

		case tk_beg:

			switch(tok){

				case tk_beg:

					op(0x84);

					op(128+64+(unsigned int)itok.number*8+hstok.number);

					break;

				case tk_number:

				 	asmparam=FALSE;

					num=doconstdwordmath();

testal:

					if(hstok.number==AL)op(0xA8);

					else{

						op(0xF6);

						op(128+64+hstok.number);

					}

					op(num);

					next=0;

					break;

				case tk_charvar:

				case tk_bytevar:

					CheckAllMassiv(bufrm,1,&strinf);

					outseg(&itok,2);

					op(0x84);

					op(hstok.number*8+itok.rm);

					outaddress(&itok);

					break;

				default: return FALSE;

			}

			break;

		case tk_dwordvar:

		case tk_longvar:

			i=r32;

			possiblecpu=3;

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(hbuf,i,&hstr,&hstok);

			switch(tok){

				case tk_reg32:

					if(i==r16){

						regexpected(2);

						return FALSE;

					}

					op66(i);

					outseg(&hstok,2);

					op(0x85);

					op((unsigned int)itok.number*8+hstok.rm);

					outaddress(&hstok);

					break;

				case tk_reg:

					if(i==r32){

						reg32expected(2);

						return FALSE;

					}

					op66(i);

					outseg(&hstok,2);

					op(0x85);

					op((unsigned int)itok.number*8+hstok.rm);

					outaddress(&hstok);

					break;

				case tk_number:

				 	asmparam=FALSE;

					num=doconstdwordmath();

					if(mode){

						if(num<256)goto testbyte;

						if(num<65536)i=r16;

					}

					op66(i);

					outseg(&hstok,2);

					op(0xF7);

					op(hstok.rm);

					outaddress(&hstok);

					if(i==r32)outdword(num);

					else outword((unsigned int)num);

					next=0;

					break;

				case tk_postnumber:

					op66(i);

					outseg(&hstok,2);

					if(i==r32)return FALSE;

					op(0xF7);

					op(hstok.rm);

					outaddress(&hstok);

					(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

					outword((unsigned int)itok.number);

					break;

				default: return FALSE;

			}

			break;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(hbuf,1,&hstr,&hstok);

			switch(tok){

				case tk_beg:

					outseg(&hstok,2);

					op(0x84);

					op((unsigned int)itok.number*8+hstok.rm);

					outaddress(&hstok);

					break;

				case tk_number:

				 	asmparam=FALSE;

					num=doconstdwordmath();

testbyte:

					outseg(&hstok,2);

					op(0xF6);

					op(hstok.rm);

					outaddress(&hstok);

					op(num);

					next=0;

					break;

				default: return FALSE;

			}

			break;

		default: return FALSE;

	}

	if(cpu<possiblecpu)cpu=possiblecpu;

	if(next)nexttok();

	return TRUE;

}



void mmxiii(int type)

{

int num1,i=1;

int xmm=FALSE;

	nexttok();

	if(tok==tk_xmmreg)xmm=TRUE;

	else if(tok!=tk_mmxreg)mmxregexpected(1);

	num1=itok.number;

	nextexpecting2(tk_camma);

	switch(tok){

		case tk_mmxreg:

			if(xmm)xmmregorvarexpected(2);

			op(0x0F);

			op(type);

			op(rm_mod11+itok.number+num1*8);

			break;

		case tk_xmmreg:

			if(xmm==FALSE)mmxormem(2);

			outword(0x0F66);

			op(type);

			op(rm_mod11+itok.number+num1*8);

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,xmm==FALSE?3:4);

			if(xmm)op(0x66);

			op(0x0F);

			op(type);

			op(itok.rm+num1*8);

			outaddress(&itok);

			break;

		default:

			mmxormem(2);

			break;

	}

	if(cpu<8)cpu=8;

	if(xmm&&cpu<9)cpu=9;

}



void prefetch(int code,int type)

{

int i=1;

	nexttok();

	switch(tok){

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(bufrm,i,&strinf);

			KillVar(itok.name);

			outseg(&itok,3);

			op(0x0f);

			op(code);

			op(itok.rm+type*8);

			outaddress(&itok);

			break;

		default:

			datatype_expected(1);

			break;

	}

}



void pextrw()

{

int num1,num2;

int xmm=FALSE;

	nexttok();

	if(tok!=tk_reg32)reg32expected(1);

	num1=itok.number;

	ClearReg(num1);

	nextexpecting2(tk_camma);

	if(tok==tk_xmmreg)xmm=TRUE;

	else if(tok!=tk_mmxreg)mmxregexpected(2);

	num2=itok.number;

	nextexpecting2(tk_camma);

	if(tok!=tk_number)numexpected(3);

	if(xmm)op(0x66);

	outword(0xC50F);

	op(rm_mod11+num1+num2*8);

	op(doconstdwordmath());

	if(cpu<8)cpu=8;

	if(xmm&&cpu<9)cpu=9;

}



void pinsrw()

{

int num1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

int xmm=FALSE;

	nexttok();

	if(tok==tk_xmmreg)xmm=TRUE;

	else if(tok!=tk_mmxreg)mmxregexpected(1);

	num1=itok.number;

	nextexpecting2(tk_camma);

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok!=tk_number)numexpected(3);

	switch(htok){

		case tk_reg32:

			if(xmm)op(0x66);

			outword(0xC40F);

			op(rm_mod11+num1+hstok.number*8);

			break;

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(hbuf,2,&hstr);

			outseg(&hstok,xmm==FALSE?3:4);

			if(xmm)op(0x66);

			outword(0xC40F);

			op(hstok.rm+num1*8);

			outaddress(&hstok);

			break;

		default:

			reg32orword(2);

			break;

	}

	op(doconstdwordmath());

	if(cpu<8)cpu=8;

	if(xmm&&cpu<9)cpu=9;

}



void pshufw()

{

int num1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

int i=1;

	nexttok();

	if(tok!=tk_mmxreg)mmxregexpected(1);

	num1=itok.number;

	nextexpecting2(tk_camma);

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok!=tk_number)numexpected(3);

	switch(htok){

		case tk_mmxreg:

			outword(0x700F);

			op(rm_mod11+num1+hstok.number*8);

			break;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(hbuf,i,&hstr);

			KillVar(hstok.name);

			outseg(&hstok,3);

			outword(0x700F);

			op(hstok.rm+num1*8);

			outaddress(&hstok);

			break;

		default:

			mmxregordwordexpected(2);

			break;

	}

	op(doconstdwordmath());

}



void xmminstr(int type,int sec,int op1,int op2)

{

int num1,i=1;

	nexttok();

	if(tok!=op1){

		if(op1==tk_mmxreg)mmxregexpected(1);

		else if(op1==tk_reg32)reg32expected(1);

		else xmmregexpected(1);

	}

	if(tok==tk_reg32)ClearReg(itok.number);

	num1=itok.number;

	nextexpecting2(tk_camma);

	switch ( tok ) {

		case tk_reg32:

		case tk_mmxreg:

		case tk_xmmreg:

			if(tok!=op2){

				if(op2==tk_mmxreg)mmxregexpected(2);

				else if(op2==tk_reg32)reg32expected(2);

				else xmmregexpected(2);

			}

			if(sec)op(sec);

			op(0x0F);

			op(type);

			op(rm_mod11+itok.number+num1*8);

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,sec==0?3:4);

			if(sec)op(sec);

			op(0x0F);

			op(type);

			op(itok.rm+num1*8);

			outaddress(&itok);

			break;

		default:

			if(op2==tk_mmxreg)mmxregordwordexpected(2);

			else if(op2==tk_reg32)reg32orword(2);

			else xmmregorvarexpected(2);

			break;

	}

}



void xmm3instr(int type,int sec)	//xmm,xmm/mem,i8

{

int num1,i=1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

	nexttok();

	if(tok!=tk_xmmreg)xmmregexpected(1);

	num1=itok.number;

	nextexpecting2(tk_camma);

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok!=tk_number)numexpected(3);

	switch(htok){

		case tk_xmmreg:

			if(sec)op(sec);

			op(0x0F);

			op(type);

			op(rm_mod11+hstok.number+num1*8);

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(hbuf,i,&hstr);

			outseg(&hstok,sec==0?3:4);

			if(sec)op(sec);

			op(0x0F);

			op(type);

			op(hstok.rm+num1*8);

			outaddress(&hstok);

			break;

		default:

			xmmregorvarexpected(2);

			break;

	}

	op(doconstdwordmath());

}



void xmm2xmm(int code,int code2,int type)

{

int num;

	nexttok();

	if(tok!=type){

		if(type==tk_mmxreg)mmxregexpected(1);

		else if(type==tk_reg32)reg32expected(1);

		else xmmregexpected(1);

	}

	if(tok==tk_reg32)ClearReg(itok.number);

	num=itok.number;

	nextexpecting2(tk_camma);

	if(tok!=tk_xmmreg)xmmregexpected(2);

	if(code2)op(code2);

	op(0x0F);

	op(code);

	op(rm_mod11+itok.number+num*8);

}



void movxmm3(int code,int code2,int type)

{

int i=1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

	nexttok();

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	if(tok!=type){

		if(type==tk_mmxreg)mmxregexpected(2);

		else if(type==tk_xmmreg)xmmregexpected(2);

		else reg32expected(2);

	}

	switch(htok){

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i+=1;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(hbuf,i,&hstr);

			KillVar(hstok.name);

			outseg(&hstok,code2==0?3:4);

			if(code2)op(code2);

			op(0x0F);

			op(code);

			op(hstok.rm+itok.number*8);

			outaddress(&hstok);

			break;

		default: varexpected(1);

	}

}



void movxmm4(int code,int code2)

{

int i=1;

int num;

	nexttok();

	num=itok.number;

	if(tok!=tk_xmmreg)xmmregexpected(1);

	nextexpecting2(tk_camma);

	switch(tok){

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i+=1;

		case tk_charvar:

		case tk_bytevar:

			CheckAllMassiv(bufrm,i,&strinf);

			outseg(&itok,(code2==0?3:4));

			if(code2)op(code2);

			op(0x0F);

			op(code);

			op(itok.rm+num*8);

			outaddress(&itok);

			break;

		default: varexpected(2);

	}

}



void movxmm(int code,int code2,int addc)

{

int i=1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

	nexttok();

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	switch(htok){

		case tk_xmmreg:

			switch(tok){

				case tk_xmmreg:

					if(code2)op(code2);

					op(0x0F);

					op(code);

					op(rm_mod11+itok.number+hstok.number*8);

					break;

				case tk_qwordvar:

					i+=4;

				case tk_longvar:

				case tk_dwordvar:

				case tk_floatvar:

					i+=2;

				case tk_wordvar:

				case tk_intvar:

					i++;

				case tk_charvar:

				case tk_bytevar:

					CheckAllMassiv(bufrm,i,&strinf);

					outseg(&itok,(code2==0?3:4));

					if(code2)op(code2);

					op(0x0F);

					op(code);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default:

					xmmregorvarexpected(2);

					break;

			}

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			if(tok!=tk_xmmreg)xmmregexpected(2);

			CheckAllMassiv(hbuf,i,&hstr);

			KillVar(hstok.name);

			outseg(&hstok,code2==0?3:4);

			if(code2)op(code2);

			op(0x0F);

			op(code+addc);

			op(hstok.rm+itok.number*8);

			outaddress(&hstok);

			break;

		default:

			xmmregorvarexpected(1);

			break;

	}

}



void movxmm2(int code,int code2)

{

int i=1,htok;

ITOK hstok;

char *hbuf;

SINFO hstr;

	nexttok();

	htok=tok;

	hstok=itok;

	hbuf=bufrm;

	bufrm=NULL;

	hstr=strinf;

	strinf.bufstr=NULL;

	nextexpecting2(tk_camma);

	switch(htok){

		case tk_xmmreg:

			switch(tok){

				case tk_qwordvar:

					i+=4;

				case tk_longvar:

				case tk_dwordvar:

				case tk_floatvar:

					i+=2;

				case tk_wordvar:

				case tk_intvar:

					i++;

				case tk_charvar:

				case tk_bytevar:

					CheckAllMassiv(bufrm,i,&strinf);

					outseg(&itok,(code2==0?3:4));

					if(code2)op(code2);

					op(0x0F);

					op(code);

					op(itok.rm+hstok.number*8);

					outaddress(&itok);

					break;

				default:

					datatype_expected(2);

					break;

			}

			break;

		case tk_qwordvar:

			i+=4;

		case tk_longvar:

		case tk_dwordvar:

		case tk_floatvar:

			i+=2;

		case tk_wordvar:

		case tk_intvar:

			i++;

		case tk_charvar:

		case tk_bytevar:

			if(tok!=tk_xmmreg)xmmregexpected(2);

			CheckAllMassiv(hbuf,i,&hstr);

			KillVar(hstok.name);

			outseg(&hstok,code2==0?3:4);

			if(code2)op(code2);

			op(0x0F);

			op(code+1);

			op(hstok.rm+itok.number*8);

			outaddress(&hstok);

			break;

		default:

			xmmregorvarexpected(1);

			break;

	}

}



void shiftxmm(int rm)	//rxmm,i8

{

int num;

	nexttok();

	if(tok!=tk_xmmreg)xmmregexpected(1);

	num=itok.number;

	nextexpecting2(tk_camma);

	if(tok!=tk_number)numexpected(2);

	op(0x66);

	op(0x0F);

	op(0x73);

	op(rm*8+num+rm_mod11);

	op(doconstdwordmath());

}



void DDDW(int faradd)

{

int htok,i;

char name[IDLENGTH];

unsigned long hnumber;

	if(dbg&2)AddDataNullLine(faradd==0?2:4);

	dbgact++;

	asmparam=FALSE;

	do{

		i=1;

		nexttok();

		CheckIP();

		htok=tok;

		switch(tok){

			case tk_undefofs:

				tok=tk_number;

				strcpy(name,itok.name);

			case tk_number:

				hnumber=doconstdwordmath();

				if(tok==tk_id&&strcmp((char *)string,"dup")==0){

					i=hnumber;

					nexttok();

					CheckMinusNum();

					htok=tok;

					if(tok==tk_undefofs){

						tok=tk_number;

						strcpy(name,itok.name);

					}

					if(tok==tk_number)hnumber=doconstdwordmath();

					else numexpected();

				}

				for(;i!=0;i--){

				 	if(postnumflag&f_reloc)AddReloc();

				 	if(htok==tk_undefofs)AddUndefOff(2,name);

					if(faradd)outdword(hnumber);

					else outword(hnumber);

				}

				break;

			case tk_postnumber:

				setwordpost(&itok);

				if(faradd)outdword(itok.number);

				else outword(itok.number);

				nexttok();

				break;

			default:

				numexpected();

				nexttok();

				break;

		}

	}while(tok==tk_camma);

	dbgact--;

}



void AADM(int code)

{

	op(code);

	itok.number=10;

	if(tok2==tk_number)nexttok();

	op(itok.number);	//AAD

	ClearReg(AX);

}



int Push(ITOK *wtok)

{

int i;

int razr;

ITOK hstok;

unsigned long hnumber;

int possiblecpu=0;

int next=1;

	i=(am32+1)*2;

	razr=r16;

	switch(tok){

		case tk_id:

		case tk_ID:

			if((stricmp("dword",(char *)string)==0)||(stricmp("long",(char *)string)==0))i=r32;

			else if((stricmp("word",(char *)string)==0)||(stricmp("int",(char *)string)==0))i=r16;

			else return FALSE;

			goto swpushpar;

		case tk_dword:

		case tk_long:

			i=r32;

			goto swpushpar;

		case tk_int:

		case tk_word:

			i=r16;

swpushpar:

			nexttok();

			CheckMinusNum();

			if(tok==tk_number)goto pushnum;

			if(tok==tk_undefofs)goto pushundef;

			return FALSE;

		case tk_reg32:

			possiblecpu=3;

		case tk_reg:

			op66(tok==tk_reg?r16:r32);

			op(0x50+(unsigned int)itok.number);

			break;

		case tk_seg:

			PushSeg((unsigned int)itok.number);

			break;

		case tk_undefofs:

pushundef:

			hstok=itok;

			tok=tk_number;

			hnumber=doconstlongmath();

			op66(i);	////

			op(0x68);

		 	if(postnumflag&f_reloc)AddReloc();

		 	AddUndefOff(2,hstok.name);

			if(i==r16)outword(hnumber);

			else outdword(hnumber);

			possiblecpu=(unsigned char)(i==r16?2:3);

			next=0;

			break;

		case tk_minus:

			if(tok2!=tk_number)return FALSE;

		case tk_number:

pushnum:

			hnumber=doconstlongmath();

			if(i==r16)hnumber&=0xffff;

			else hnumber&=0xffffffff;

			if(wtok&&(postnumflag&f_reloc)==0)Const2Var(wtok,hnumber,i==r16?tk_word:tk_dword);

			op66(i);

			if((postnumflag&f_reloc)==0&&short_ok(hnumber,i/2-1)){

				op(0x6A);

				op(hnumber);

			}

			else{

				op(0x68);

				if((postnumflag&f_reloc)!=0)AddReloc();

				if(i==r16)outword(hnumber);

				else outdword(hnumber);

			}

			possiblecpu=(unsigned char)(i==r16?2:3);

			next=0;

			break;

		case tk_dwordvar:

		case tk_longvar:

			CheckAllMassiv(bufrm,4,&strinf);

			possiblecpu=3;

			razr=r32;

			goto push;

		case tk_wordvar:

		case tk_intvar:

			CheckAllMassiv(bufrm,2,&strinf);

push:

			op66(razr);

			outseg(&itok,2);

			op(0xFF);	op(0x30+itok.rm);

			outaddress(&itok);

			break;

		case tk_postnumber:

			op(0x68);

			(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);

			if(am32==FALSE)outword((unsigned int)itok.number);

			else outdword(itok.number);

			break;

		case tk_string:

			op66(i);

			op(0x68);

			if(am32==FALSE)outword(addpoststring());

			else outdword(addpoststring());

			break;

		default:

			return FALSE;

	}

	if(cpu<possiblecpu)cpu=possiblecpu;

	asmparam=FALSE;

	if(next)nexttok();

	return i;

}

/* end of TOKR.C */