#define _POINTER_



#include "tok.h"



void dopointerproc()

{

unsigned int snum;

int razr=r16;

ITOK wtok;

char *wbuf;

SINFO wstr;

	if(am32)razr=r32;

	itok.rm=itok.sib;

	itok.sib=am32==0?CODE16:CODE32;

	if((FixUp)



	&&((itok.rm==rm_d32&&am32)||(itok.rm==rm_d16&&am32==0)))//16.07.04 16:01

	//18.08.04 18:03  itok.rm==rm_d32 was itok.rm==CODE32



	itok.flag|=f_reloc;

	else compressoffset(&itok);

	wstr=strinf;

	strinf.bufstr=NULL;

	wtok=itok;

	wbuf=bufrm;

	bufrm=NULL;

	unsigned int oaddESP=addESP;

	if(wtok.npointr<2){

		itok.flag&=~f_far;

//		itok.post=0;

		snum=initparamproc();

		CheckAllMassiv(wbuf,razr,&wstr,&wtok);

		outseg(&wtok,2);

		op(0xFF); op(0x10+wtok.rm+((wtok.flag&f_far)!=0?8:0));

		outaddress(&wtok);

	}

	else{

int reg=BX;

		getpointeradr(&wtok,wbuf,&wstr,wtok.npointr-1,am32==0?r16:r32,reg);

		snum=initparamproc();

		op66(razr);

		op(0xFF);

		op(0xD0+reg); 	/* CALL reg with stack params */

	}

	if((wtok.flag&f_typeproc)==tp_cdecl)CorrectStack(snum);

	else addESP=oaddESP;

	clearregstat(0);

}



void dopointer()

{

	if(itok.type==tk_proc){

		if(tok2==tk_openbracket){

			dopointerproc();

			nexttok();

			return;

		}

		itok.rm=itok.sib;

		itok.sib=am32==0?CODE16:CODE32;

		compressoffset(&itok);

	}

int razr=r16;

	if(am32||(itok.flag&f_far))razr=r32;

	do_d_wordvar(0,razr);

}



void getpointeradr(ITOK *gstok,char *&gbuf,SINFO *gstr,int numpointer,int razr, int reg)

{

	if(gstok->flag&f_far){

		CheckAllMassiv(gbuf,4,gstr,gstok);

		outseg(gstok,2);

		op(0xC4);

		op(gstok->rm+8*reg);

		outaddress(gstok);

		itok.segm=ES;

		itok.sib=CODE16;

		if(reg==BX)itok.rm=rm_BX;

		else if(reg==SI)itok.rm=rm_SI;

		else if(reg==DI)itok.rm=rm_DI;

		warningreg(segs[0]);

	}

	else{

		int retreg;

		if((gstok->flag&f_useidx)==0&&(retreg=CheckIDZReg(gstok->name,reg,razr))!=NOINREG){

			if(am32==0&&retreg!=BX&&retreg!=SI&&retreg!=DI){

				GenRegToReg(reg,retreg,razr);

				IDZToReg(gstok->name,reg,razr);

			}

			else if(retreg!=SKIPREG)reg=retreg;

			if(gbuf){

				free(gbuf);

				gbuf=NULL;

			}

			if(gstr->bufstr){

				free(gstr->bufstr);

				gstr->bufstr=NULL;

			}

			goto nomov;

		}

		if((gstok->flag&f_useidx))IDZToReg(gstok->name,reg,razr);

		CheckAllMassiv(gbuf,razr,gstr,gstok);

		outseg(gstok,2);

		op(0x8B);

		op(reg*8+gstok->rm);

		outaddress(gstok);

nomov:

		itok.segm=DS;

		if(am32==0){

			itok.sib=CODE16;

			if(reg==BX)itok.rm=rm_BX;

			else if(reg==SI)itok.rm=rm_SI;

			else if(reg==DI)itok.rm=rm_DI;

		}

		else{

			itok.sib=CODE32;

			itok.rm=reg;

		}

	}

	itok.post=0;

	itok.number=0;

	itok.flag=gstok->flag&(!f_reloc);

	warningreg(regs[am32][reg]);

	while(numpointer){

		outseg(&itok,2);

		op(0x8B);

		op(itok.rm+reg*8);

		outaddress(&itok);

		numpointer--;

	}

}



void dovalpointer()

{

int sign=0,rettype,pointr,razr=r8;

int rrettype;

int numpointer=0;

int hnumber=0;

//int i=0;

int reg=BX;

int npointr=0;

	do{

		nexttok();

		numpointer++;

	}while(tok==tk_mult);

ITOK wtok;

char *wbuf;

SINFO wstr;

unsigned char ocha;

unsigned int oinptr;

unsigned int olinenum;

int otok2;

	wstr=strinf;

	strinf.bufstr=NULL;

	wtok=itok;

	wbuf=bufrm;

	bufrm=NULL;

	if(numpointer==itok.npointr){

		switch(itok.type){

			case tk_qword:

			case tk_double:

				razr+=4;

			case tk_dword:

			case tk_float:

				razr+=2;

			case tk_word:

				razr++;

				break;

			case tk_long:

				razr+=2;

			case tk_int:

				razr++;

			case tk_char:

				sign=1;

				break;

		}

		rrettype=rettype=itok.type;

		oinptr=inptr2;

		ocha=cha2;

		olinenum=linenumber;

		otok2=tok2;

		nexttok();

		if(tok==tk_assign){

			nexttok();

			convert_type(&sign,(int *)&rettype,&pointr);

			while(tok==tk_mult){

				nexttok();

				npointr++;

			}

			if(npointr>itok.npointr)unuseableinput();

			if(tok2==tk_assign){

				hnumber=MultiAssign(razr,USEALLREG,npointr);

				if(reg==hnumber)reg=DI;

				goto getfromax;

			}

		}

		linenumber=linenum2=olinenum;

		cha2=ocha;

		inptr2=oinptr;

		tok2=otok2;

		itok=wtok;

		if(itok.type==tk_proc){

			dopointer();

			return;

		}

		getpointeradr(&itok,wbuf,&wstr,numpointer-1,razr,reg);

		tok=tk_charvar+itok.type-tk_char;

		switch(itok.type){

			case tk_long:

			case tk_dword:

			case tk_int:

			case tk_word:

				do_d_wordvar(sign,razr);

				return;

			case tk_char:

			case tk_byte:

				dobytevar(sign);

				return;

			case tk_float:

				dofloatvar();

				return;

			case tk_qword:

				doqwordvar();

				return;

			case tk_double:

//				dodoublevar();

				return;

		}

getfromax:

		convert_returnvalue(rrettype,rettype);

ITOK otok=itok;

		getpointeradr(&wtok,wbuf,&wstr,numpointer-1,razr,reg);

		switch(rrettype){

			case tk_char:

			case tk_byte:

				outseg(&itok,2);

				op(0x88);

				op(itok.rm+hnumber*8);	//[reg]=AL

				break;

			case tk_int:

			case tk_word:

			case tk_long:

			case tk_dword:

			case tk_qword:

				op66(razr);

				outseg(&itok,2);

				op(0x89);

				op(itok.rm+hnumber*8); // MOV [rmword],AX

				break;

			case tk_float:

				outseg(&itok,2);	//fstp var

				op(0xd9);

				op(itok.rm+0x18);

				fwait3();

				break;

			case tk_double:

				outseg(&itok,2);	//fstpq var

				op(0xdd);

				op(itok.rm+0x18);

				fwait3();

				break;

		}

		itok=otok;

	}

	else if(numpointer<itok.npointr){

		razr=r16;

		rettype=tk_word;

		if(am32||(itok.flag&f_far)){

			razr=r32;

			rettype=tk_dword;

		}

		rrettype=rettype;

		doreg_32(AX,razr);

		goto getfromax;

	}

	else unuseableinput();

}