#define _TOKC_
#include <fcntl.h> /* O_ constant definitions */
#include <unistd.h>
#include "tok.h"
void GetFileTime(int fd,struct ftime *buf);
#define MAXIF 32
//idrec *crec=NULL;
char invaliddecrem[]="invalid token to be decremented";
char mesLOOPNZ[]="LOOPNZ";
char mesIF[]="IF";
char mesELSE[]="ELSE";
char mesWHILE[]="WHILE";
char mesFOR[]="FOR";
char mesRETURN[]="RETURN";
int tok,tok2; /* token holders current, next */
unsigned char string[STRLEN],string2[STRLEN+20],
string3[STRLEN]; //ёюфхЁцшЄ эх яЁхюсЁрчютрээє■ ёЄЁюъє
unsigned int posts=0; /* number of post entrys */
postinfo *postbuf;
unsigned int maxposts=MAXPOSTS;
unsigned int secondcallnum=1; /* # of different second calls and labels */
unsigned int externnum=0;
unsigned long postsize=0; /* total size of all post vars */
unsigned int poststrptr=0; /* post string index in output */
unsigned int outptrsize=MAXDATA; //ЁрчьхЁ т√їюфэюую сєЇхЁр фы ъюфр
unsigned int outdatasize=MAXDATA; //ЁрчьхЁ т√їюфэюую сєЇхЁр фы фрээ√ї
long runfilesize;
int error=0; /* current error number holder */
unsigned char dos1=0,dos2=0; /* DOS version required for program execution */
unsigned char cpu=0; /* CPU required, 2 for 80286, 3 for 80386, ... */
unsigned int paramsize=0; /* byte size of all procedure parameters */
unsigned int localsize=0; /* byte size of all procedure local variables */
unsigned int procedure_start=0; /* address of start of procedure */
unsigned int current_proc_type; /* current procedure type */
int returntype; /* return type, (void, byte, word, ...) */
unsigned char warning;
/*+++++++++++++++++++++++ ╙ёЄрэютъш яю єьюыўрэш■ +++++++++++++++++++++++*/
unsigned char am32 = FALSE; // Ёхцшь 32 сшЄэющ рфЁхёрЎшш
unsigned char comfile = file_com; // output file format
unsigned char optimizespeed = 1; // optimize for size or speed flag
unsigned char alignword = 1; // flag whether or not to align words
unsigned char aligner = 0; // value used to align words
unsigned char header = 1; // output SPHINX C-- Ver1 Ver2 header
unsigned char chip = 0; // CPU optimization (286,386,486,...)
unsigned char killctrlc = 0; // add disable CTRL-C code in header
unsigned int stacksize = 2048; // stack size (2048 default)
unsigned char splitdata=FALSE; //юЄфхышЄ№ фрээ√х юЄ ъюфр
unsigned char AlignCycle=FALSE; //т√ЁртэштрЄ№ эрўрыр Ўшъыют
/*+++++++++++++++++++ end of flexable compiler options ++++++++++++++++++++*/
unsigned char notdoneprestuff = TRUE; // flag if initial stuff has been entered
unsigned int datasize=0,alignersize=0; /* size of data and other */
unsigned int outptr=0x100,outptrdata=0x100; /* ptr to output */
unsigned char *output;
unsigned char *outputdata=NULL;
unsigned int linenumber=0;
unsigned char dynamic_flag=0; //Їыру юсЁрсюЄъш фшэрьшўхёъшї ¤ыхьхэЄют
unsigned char *input; /* dynamic input buffer */
unsigned int endinptr; /* end index of input array */
unsigned int inptr; /* index in input buffer */
unsigned char cha; /* pipe byte for token production */
char endoffile; /* end of input file flag */
unsigned char insertmode=FALSE;
unsigned int numblocks=0; //эюьхЁ тыюцхээюую сыюър
treelocalrec *tlr=NULL; //Ўхяюўър ыюъры№э√ї сыюъют
treelocalrec *btlr=NULL; //Ўхяюўър шёяюы№чютрэ√ї ыюъры№э√ї сыюъют
RETLIST *listreturn=NULL;
unsigned int numreturn=0;
idrec *staticlist;
unsigned char stat_reg[8]; //ЄрсышЎр чрэ ЄюёЄш ЁхушёЄЁют
int sizestack=0; //ЁрчьхЁ эх ъюьяхэёшЁютрээ√ї ярЁрьхЄЁют ЇєэъЎшщ
unsigned char addstack=TRUE;
extern char shorterr[];
extern unsigned long long li[];
/*-----------------01.05.98 19:22-------------------
фюяюыэшЄхы№э√х яхЁхьхээ√х фы ЁхрышчрЎшш BREAK CONTINUE
--------------------------------------------------*/
#define MAXIN 100 //ьръёшьры№эр тыюцхэюёЄ№ Ўшъыют
unsigned int numbr=0; //ёўхЄўшъ юс∙хую ўшёыр Ўшъыют LOOP DO-WHILE...
unsigned int listbr[MAXIN]; //ЄрсышЎр эюьхЁют Ўшъыют
unsigned int usebr[MAXIN]; //шёяюы№чютрэю break
unsigned int useco[MAXIN]; //шёяюы№чютрэю continue
unsigned int curbr=0,curco=0; //Єхъє∙р тыюцхэюёЄ№ Ўшъыют
unsigned int startStartup=0x100;
unsigned int endStartup=0;
unsigned char useStartup=FALSE;
unsigned char notpost=FALSE;
int retproc;
int lastcommand; //яюёыхфэшщ юяхЁрЄюЁ т сыюъх
unsigned char FastCallApi=TRUE; //ЁрчЁх°шЄ№ с√ёЄЁ√щ т√чют API яЁюЎхфєЁ
unsigned char FixUp=FALSE; //─хырЄ№ ыш ЄрсышЎє яхЁхьх∙хэшщ
unsigned char AlignProc=FALSE;
//------- ЁрсюЄр ё union ---------------------------------------------
char param[256]; //сєЇхЁ фы ярЁрьхЄЁют яЁюЎхфєЁ√
char *BackTextBlock; //сєЇхЁ фы яхЁхэхёхээюую ЄхъёЄр
int SizeBackBuf=0,MaxSizeBackBuf;
struct FILEINFO *startfileinfo=NULL;
unsigned int totalmodule=0;
unsigned int currentfileinfo;
unsigned char setzeroflag; //юяхЁрЎш ьхэ хЄ zero flag
unsigned char notunreach=FALSE;
unsigned int initBP=0;
int inlineflag=0; // flag for disabling entry and exit codes production
unsigned char fstatic=FALSE;
unsigned long addESP=0; //фюсртър ёЄхър
unsigned char blockproc=FALSE; //шфхЄЁрчсюЁър сыюър ЇєэъЎшш
unsigned int updatelocalvar(char *str,int tok,unsigned int num);
void setuprm();
void doloop(unsigned int typeb); /* both short and long loops */
void doBREAK(unsigned char typeb);
void doCONTINUE(unsigned char typeb);
void dowhile(unsigned int typeb);
void MakeContinue(unsigned char typeb);
void dofor(unsigned int typeb);
void dodo();
void globalvar(); /* both initialized and unitialized combined */
void doswitch();
void CalcRegPar(int reg,int def,char *&ofsstr);
void JXorJMP();
int loadinputfile(char *inpfile);
int SaveStartUp(int size,char *var_name);
void LoadData(unsigned int size,int filehandle);
void SetNewTok(int type,int typev);
void doreturn(int type=tokens); /* do return(...); */
void notnegit(int notneg);
void insertcode(); // force code procedure at specified location
void interruptproc();
void dobigif();
void doif(void);
void doasmblock();
void declareextern();
unsigned long dounion(int,int);
void RunBackText();
int FindDublString(int segm,unsigned int len,int term);
void *liststring=NULL; //Ўхяюўър шэЇюЁьрЎшюээ√ї сыюъют ю ёЄЁюърї
void GetNameLabel(int type,int num);
void CheckPosts();
SAVEPAR *SRparam(int save,SAVEPAR *par); //save or restore global param compiler
void AddRetList(int pos,int line,int type);
void CheckRealizable();
void declare_procedure(int oflag,int orm,int npointr);
void labelindata();
void AddRegistr(int razr,int reg);
void ClearRegister();
int GetRegister(int mode=0);
void RegAddNum(int reg);
void dowhilefast(unsigned int typeb);
int getrazr(int type);
void RestoreSaveReg();
void killlocals(/*int endp=TRUE*/);
void leaveproc();
int IsSaveReg();
void CorrectParamVar();
extern void ManyLogicCompare();
extern void maxdataerror();
extern void CompareOr();
extern void dynamiclabelerror();
extern void retvoid();
extern int numberbreak;
SAVEREG savereg;
SAVEREG *psavereg=&savereg;
int loadfile(char *filename,int firstflag)
{
int hold;
for(int i=0;i<=numfindpath;i++){
sprintf((char *)string2,"%s%s",findpath[(firstflag==0?i:numfindpath-i)],filename);
if((hold=loadinputfile((char *)string2))!=-2)break;
if(firstflag==2||(firstflag==0&&(i+1)==numfindpath))break;
}
if(hold==-2){
unableopenfile(filename); //ёююс∙хэшх ю ю°шсъх
exit(e_cannotopeninput); //чртхЁ°шЄ№ ЁрсюЄє хёыш эх ёьюуыш чруЁєчшЄ№ Їрщы
}
return hold;
}
void compilefile(char *filename,int firstflag)
{
int hold;
hold=loadfile(filename,firstflag);
if(hold==1||hold==-1)return;
if(strcmp(filename,"startup.h--")==0)startupfile=currentfileinfo;
inptr=0;
endoffile=0;
startline=(char*)input;
endinput=startline+endinptr;
warning=gwarning;
nextchar();
cha2=cha; //ёшьтюы шч сєЇхЁр
inptr2=inptr; //чряюьэ єърчрЄхы№ эр ёыхф ёшьтюы
linenum2=1; //эюьхЁ ёЄЁюъш
{ //яЁютхЁър эр Їрщы ЁхёєЁёют ш хую юсЁрсюЄър
char *a;
if((a=strrchr(filename,'.'))!=NULL){
if(stricmp(a,".rc")==0){
input_res();
free(input);
return;
}
}
}
nexttok(); //юяЁ Єшя яхЁтюую ш тЄюЁюую Єюъхэр
while(tok!=tk_eof){ //Ўшъы яюър эх ъюэўшЄё Їрщы
while(tok==tk_question){
directive();//юсЁрсюЄър фшЁхъЄшт
if(tok==tk_semicolon)nexttok();
}
usedirectiv=FALSE;
if(notdoneprestuff==TRUE)doprestuff();//startup
switch(tok){
case tk_ID:
case tk_id:
if(FindTeg(TRUE)!=NULL){
InitStruct();
break;
}
if(tok2==tk_colon){
labelindata();
break;
}
case tk_far:
case tk_cdecl:
case tk_pascal:
case tk_stdcall:
case tk_fastcall:
case tk_declare:
case tk_undefproc:
case tk_float:
case tk_long:
case tk_dword:
case tk_word:
case tk_byte:
case tk_char:
case tk_int:
case tk_void:
case tk_export:
case tk_qword:
case tk_double:
case tk_fpust:
if((hold=testInitVar())==FALSE)define_procedure();
else if(hold==TRUE)globalvar();
break;
case tk_struct: InitStruct(); break;
case tk_interrupt: interruptproc(); break;
case tk_at: insertcode(); break; //тёЄртър ЁхушёЄЁютющ яЁюЎхфєЁ√
case tk_colon:
nexttok();
dynamic_flag=2;
break;// юяЁ фшэрьшўхёъющ яЁюЎхфєЁ√
case tk_inline:
if(testInitVar()){
preerror("Bad header dynamic function");
nexttok();
}
dynamic_proc();
break;
case tk_static:
fstatic=2;
nexttok();
break;
case tk_enum: doenum(); break;
case tk_from: nexttok(); dofrom(); nextseminext(); break;
case tk_extract: nexttok(); doextract(); seminext(); break;
case tk_loop:
case tk_while:
case tk_do:
case tk_else:
case tk_ELSE:
case tk_if:
case tk_IF:
case tk_interruptproc:
case tk_proc:
case tk_charvar:
case tk_intvar:
case tk_bytevar:
case tk_longvar:
case tk_dwordvar:
case tk_floatvar:
case tk_qwordvar:
case tk_doublevar:
case tk_wordvar: idalreadydefined(); break;
case tk_reg32:
case tk_debugreg:
case tk_controlreg:
case tk_testreg:
case tk_reg:
case tk_seg:
case tk_beg:
case tk_reg64:
preerror("register name cannot be used as an identifier");
nexttok();
case tk_eof: break;
case tk_locallabel: internalerror("local label token found outside function block."); break;
case tk_extern: declareextern(); break;
case tk_union: dynamic_flag=0; dounion(TRUE,fstatic==0?0:f_static); break;
case tk_semicolon: nexttok(); break;
case tk_asm:
if(tok2==tk_openbrace)doasmblock();
else doasm();
break;
case tk_idasm: doasm(TRUE); break;
case tk_dollar: doasm(FALSE); break;
default: unuseableinput();
/* while(itok.type==tp_stopper&&tok!=tk_eof)*/nexttok();
break;
}
if(fstatic)fstatic--;
else if(dynamic_flag)dynamic_flag--;
}
(startfileinfo+currentfileinfo)->stlist=staticlist;
free(input);
}
/* ------------------- output procedures start ------------------- */
int CheckCodeSize()
//яЁютхЁър ЁрчьхЁр сєЇхЁр фы ъюфр
{
if(!am32){
maxoutputerror();
return FALSE;
}
outptrsize+=MAXDATA;
output=(unsigned char *)REALLOC(output,outptrsize);
if(splitdata==FALSE)outputdata=output;
return TRUE;
}
int CheckDataSize()
//яЁютхЁър ЁрчьхЁр сєЇхЁр фы ъюфр
{
if(!am32){
maxoutputerror();
return FALSE;
}
outdatasize+=MAXDATA;
outputdata=(unsigned char *)REALLOC(outputdata,outdatasize);
return TRUE;
}
void op(int byte)
{
if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return;
output[outptr++]=(unsigned char)byte;
if(splitdata==FALSE)outptrdata=outptr;
retproc=FALSE;
}
void opd(int byte)
{
if(splitdata==FALSE){
if(outptr>=outptrsize&&CheckCodeSize()==FALSE)return;
output[outptr++]=(unsigned char)byte;
outptrdata=outptr;
}
else{
if(outptrdata>=outdatasize&&CheckDataSize()==FALSE)return;
outputdata[outptrdata++]=(unsigned char)byte;
}
}
void CorrectOfsBit(int bitofs)
{
bitofs=(bitofs+7)/8;
if(splitdata)outptrdata+=bitofs;
else{
outptr+=bitofs;
outptrdata=outptr;
}
}
long GetBitMask(int ofs,int size)
{
return (~((li[size]-1)<<ofs));
}
void opb(unsigned long num,unsigned int ofs,unsigned int size)
{
int s;
//яЁютхЁшЄ№ т√їюф чр уЁрэшЎ√ сыюър ярь Єш
s=(ofs+size+7)/8;
if(splitdata==FALSE){
if((outptr+s+8)>=outptrsize&&CheckCodeSize()==FALSE)return;
}
else{
if((outptrdata+s+8)>=outdatasize&&CheckDataSize()==FALSE)return;
}
if(size!=32)num=num&(li[size]-1);
s=outptrdata+ofs/8;
ofs=ofs%8;
*(long *)&outputdata[s]&=GetBitMask(ofs,size);
*(long *)&outputdata[s]|=(num<<ofs);
// printf("ofs=%Xh mask=%X value=%X\n",s,GetBitMask(ofs,size),(num<<ofs));
if((ofs+size)>32){
*(long *)&outputdata[s+4]&=GetBitMask(0,ofs+size-32);
*(long *)&outputdata[s+4]|=(num>>(64-ofs-size));
// printf("continue ofs=%Xh mask=%X value=%X\n",s+4,GetBitMask(0,ofs+size-32),num>>(64-ofs-size));
}
}
void outword(unsigned int num)
{
op(num);
op(num/256);
}
void outwordd(unsigned int num)
{
opd(num);
opd(num/256);
}
void outdword(unsigned long num)
{
outword((unsigned int)(num&0xFFFFL));
outword((unsigned int)(num/0x10000L));
}
void outdwordd(unsigned long num)
{
outwordd((unsigned int)(num&0xFFFFL));
outwordd((unsigned int)(num/0x10000L));
}
void outqword(unsigned long long num)
{
outdword((unsigned long)(num&0xFFFFFFFFL));
outdword((unsigned long)(num/0x100000000LL));
}
void outqwordd(unsigned long long num)
{
outdwordd((unsigned long)(num&0xFFFFFFFFL));
outdwordd((unsigned long)(num/0x100000000LL));
}
void doasmblock()
{
nexttok();
useasm=TRUE;
expecting(tk_openbrace);
for(;;){
if(tok==tk_closebrace)break;
if(tok==tk_eof){
unexpectedeof();
break;
}
lastcommand=tok;
if(dbg)AddLine();
doasm(TRUE);
}
useasm=FALSE;
nexttok();
}
void doblock()
{
expecting(tk_openbrace);
doblock2();
/* for(;;){
if(tok==tk_closebrace)break;
if(tok==tk_eof){
unexpectedeof();
break;
}
docommand();
}
RestoreStack();*/
}
void doblock2()
{
for(;;){
if(tok==tk_closebrace)break;
if(tok==tk_eof){
unexpectedeof();
break;
}
docommand();
}
if(numblocks==1&&addstack&&sizestack&&localsize&&am32&&ESPloc&&IsSaveReg()==FALSE){
localsize+=sizestack;
sizestack=0;
}
else RestoreStack();
}
void gotodo()
{
nexttok();
if(gotol(0))nexttok();
seminext();
}
void GOTOdo()
{
nexttok();
if(GOTO())nexttok();
seminext();
}
void docommand() /* do a single command */
{
unsigned int useflag;
useflag=0;
if(dbg)AddLine();
//loops:
lastcommand=tok;
// printf("tok=%d %s\n",tok,itok.name);
switch(tok){
case tk_ID: useflag++;
case tk_id:
if((useflag=doid((char)useflag,tk_void))!=tokens){
nextseminext();
if(useflag==tk_fpust)preerror("function returned parametr in FPU stack");
}
else if(tok!=tk_closebrace)docommand();
break;
case tk_apiproc:
case tk_undefproc:
case tk_declare:
if(doanyundefproc()!=tokens)nextseminext();
else if(tok!=tk_closebrace)docommand();
break;
case tk_proc:
doanyproc();
nextseminext();
break;
case tk_interruptproc:
outword(0x0E9C); //pushf //push cs
useflag=itok.post;
callloc(itok.number);
nexttok();
expecting(tk_openbracket);
expecting(tk_closebracket);
#ifdef OPTVARCONST
FreeGlobalConst();
#endif
seminext();
clearregstat(useflag);
break;
case tk_bits:
dobits();
break;
case tk_charvar: useflag=1;
case tk_bytevar:
dobytevar(useflag);
break;
case tk_intvar: useflag=1;
case tk_wordvar:
do_d_wordvar(useflag,r16);
break;
case tk_longvar: useflag=1;
case tk_dwordvar:
do_d_wordvar(useflag,r32);
break;
case tk_doublevar:
useflag=4;
case tk_floatvar:
dofloatvar(useflag,tk_floatvar,tk_semicolon);
break;
case tk_qwordvar:
doqwordvar();
break;
case tk_fpust:
dofloatstack(itok.number);
break;
case tk_structvar:
dostruct();
break;
case tk_pointer:
dopointer();
break;
case tk_mult:
dovalpointer();
break;
case tk_RETURN:
case tk_return:
RestoreStack();
#ifdef OPTVARCONST
ClearLVIC();
#endif
doreturn(tok);
CheckRealizable();
break;
case tk_at:
nexttok();
if(tok2==tk_colon){
LLabel();
if(tok!=tk_closebrace)docommand();
}
else if(macros(tk_void)!=0)nextseminext();
break;
case tk_if: RestoreStack(); doif(); break;
case tk_IF: RestoreStack(); dobigif(); break;
case tk_loopnz:
case tk_LOOPNZ:
case tk_loop: RestoreStack(); doloop(tok); break;
case tk_while:
case tk_WHILE: RestoreStack(); dowhilefast(tok); break;
case tk_do: RestoreStack(); dodo(); break;
case tk_for:
case tk_FOR: RestoreStack(); dofor(tok); break;
case tk_reg32: doreg_32((unsigned int)itok.number,r32); break;
case tk_reg: doreg_32((unsigned int)itok.number,r16); break;
case tk_beg: dobeg((unsigned int)itok.number); break;
case tk_reg64: doreg64(itok.number); break;
case tk_seg: doseg((unsigned int)itok.number); break;
case tk_openbrace:
startblock();
doblock();
nexttok();
endblock();
break;
case tk_from: nexttok(); dofrom(); nextseminext(); break;
case tk_extract: nexttok(); doextract(); seminext(); break;
case tk_minus: useflag=8;
case tk_not:
notnegit(useflag);
nextseminext();
break;
case tk_locallabel: RestoreStack(); define_locallabel(); break;
case tk_camma:
case tk_semicolon: nexttok(); break;
case tk_else:
preerror("else without preceeding if or IF");
nexttok();
break;
case tk_ELSE:
preerror("ELSE without preceeding IF or if");
nexttok();
break;
case tk_eof: unexpectedeof(); break;
case tk_void:
case tk_long:
case tk_dword:
case tk_word:
case tk_byte:
case tk_int:
case tk_char:
preerror("cannot declare variables within function { } block");
nexttok();
break;
case tk_GOTO:
RestoreStack();
GOTOdo();
CheckRealizable();
break;
case tk_goto:
RestoreStack();
gotodo();
CheckRealizable();
break;
case tk_BREAK:
RestoreStack();
doBREAK(BREAK_SHORT);
CheckRealizable();
break;
case tk_break:
RestoreStack();
doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32));
CheckRealizable();
break;
case tk_CONTINUE:
RestoreStack();
doCONTINUE(CONTINUE_SHORT);
CheckRealizable();
break;
case tk_continue:
RestoreStack();
doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32));
CheckRealizable();
break;
case tk_asm:
if(tok2==tk_openbrace)doasmblock();
else doasm();
break;
case tk_idasm:
useflag=TRUE;
case tk_dollar:
doasm(useflag);
break;
case tk_SWITCH:
case tk_switch: RestoreStack(); doswitch(); break;
case tk_delete: dodelete(); break;
case tk_new: donew(); seminext(); break;
case tk_question:
// calcnumber=FALSE;
while(tok==tk_question)directive();
break;
/* case tk_openbracket:
nexttok();
nexttok();
expectingoperand(tk_closebracket);
goto loops;*/
default: unuseableinput(); break;
}
notunreach=FALSE;
}
void doBREAK(unsigned char typeb)
{
if(curbr==0)preerror("'BREAK' or 'break' use only in loop, do-while..");
else MakeBreak(typeb);
nextseminext();
}
void doCONTINUE(unsigned char typeb)
{
if(curco==0)preerror("'CONTINUE' or 'continue' use only in loop, do-while..");
else MakeContinue(typeb);
nextseminext();
}
void MakeBreak(unsigned char typeb)
{
unsigned int nbr=0;
if(tok2==tk_number){
nexttok();
nbr=itok.number;
if(nbr>=curbr)preerror("'BREAK' or 'break' on incorrect number skip cycle");
}
numberbreak=nbr;
nbr=curbr-1-nbr;
if(usebr[nbr]==0){
GetNameLabel(tk_break,nbr);
addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE);
usebr[nbr]=secondcallnum;
secondcallnum++;
}
addacall(usebr[nbr],typeb);
if(typeb==BREAK_SHORT)outword(0x00EB); // JMP SHORT
else jumploc0();
}
void MakeContinue(unsigned char typeb)
{
unsigned int nbr=0;
if(tok2==tk_number){
nexttok();
nbr=itok.number;
if(nbr>=curco)preerror("'CONTINUE' or 'continue' on incorrect number skip cycle");
}
nbr=curco-1-nbr;
if(useco[nbr]==0){
GetNameLabel(tk_continue,nbr);
// printf("%s nbr=%d\n",(char *)string2,nbr);
addlocalvar((char *)string2,tk_locallabel,secondcallnum,TRUE);
useco[nbr]=secondcallnum;
secondcallnum++;
}
addacall(useco[nbr],typeb);
if(typeb==CONTINUE_SHORT)outword(0x00EB); // JMP SHORT
else jumploc0();
}
int CheckExitProc()
{
if(strcmp(itok.name,"EXIT")==0||strcmp(itok.name,"ABORT")==0)return TRUE;
return FALSE;
}
void LLabel()
{
localrec *ptr;
#ifdef OPTVARCONST
ClearLVIC();
#endif
RestoreStack();
clearregstat();
switch(tok){
case tk_id:
case tk_ID:
FindOff((unsigned char *)itok.name,CS);
ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
if(FixUp)ptr->rec.flag=f_reloc;
break;
case tk_undefproc:
ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);//фюсртшЄ№ т ыюъры№э√щ ёяшёюъ
if(FixUp)ptr->rec.flag=f_reloc;
updatecall((unsigned int)itok.number,outptr,procedure_start);//юсЁрсюЄрЄ№ Ёрээшх юсЁр∙хэш
break;
default:
preerror("error declaretion local label");
break;
}
nexttok();
nexttok();
}
void AddApiToPost(unsigned int num)
{
CheckPosts();
(postbuf+posts)->type=CALL_32I;
(postbuf+posts)->loc=outptr;
(postbuf+posts)->num=num;
posts++;
outdword(0);
}
/* ---------------------- Procedure Calling Starts -------------------- */
int doanyundefproc(int jumpsend)
{
unsigned int cnum,snum;
int returnvalue;
int regs;
char fname[IDLENGTH];
if(tok2==tk_colon){ // if a label
#ifdef OPTVARCONST
ClearLVIC();
#endif
RestoreStack();
clearregstat();
if(CidOrID()==tk_ID){//local label that has been used, but not placed
localrec *ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
if(FixUp)ptr->rec.flag=f_reloc;
updatecall((unsigned int)itok.number,outptr,procedure_start);//юсЁрсюЄрЄ№ Ёрээшх юсЁр∙хэш
}
else{ //уыюсры№эр ьхЄър
tok=tk_proc;
itok.number=outptr;
string[0]=0;
updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0);
}
nexttok(); // move past id
nexttok(); // move past :
return(tokens);
}
if(tok2==tk_openbracket){
strcpy(fname,itok.name);
if(tok==tk_declare){ //ёьхэшЄ№ ёЄрЄєё яЁюЎхфєЁ√ ё юс· тыхэющ эр эхшчтхёЄэє■
tok=tk_undefproc;
updatetree();
if(itok.flag&f_classproc)AddUndefClassProc();
}
cnum=(unsigned int)itok.number;
regs=itok.post;
returnvalue=itok.rm;
unsigned int tproc=itok.flag;
unsigned char apiproc=FALSE;
unsigned int oaddESP=addESP;
int sizestack=-1;
if(tok==tk_apiproc){
apiproc=TRUE;
sizestack=itok.size; //ЁрчьхЁ ёЄхър яюф ярЁрьхЄЁ√
}
#ifdef OPTVARCONST
if(tproc&f_useidx)ClearLVIC();
else FreeGlobalConst();
#endif
int exitproc=CheckExitProc();
snum=initparamproc();
if(sizestack!=-1){
if(snum>(unsigned int)sizestack)extraparam(fname);
else if(snum<(unsigned int)sizestack)missingpar(fname);
}
if((tproc&f_typeproc)!=tp_cdecl){
snum=0;
addESP=oaddESP;
}
if(FastCallApi==TRUE&&apiproc!=FALSE){
if(jumpsend)outword(0x25ff);
else outword(0x15FF);
AddApiToPost(cnum);
}
else{
addacall(cnum,(unsigned char)((tproc&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR)));
if(jumpsend)jumploc0();
else callloc0(); /* produce CALL [#] */
}
clearregstat(regs);
if(snum!=0&&jumpsend==FALSE)CorrectStack(snum);
retproc=exitproc;
return(returnvalue);
}
thisundefined(itok.name);
nexttok();
return(tk_long);
}
void CorrectStack(unsigned int num)
{
if(addstack){
sizestack+=num;
// printf("%s(%d)> Add %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,num);
}
else{
if(short_ok(num)){
outword(0xC483);
op(num);
}
else{
outword(0xC481);
if(am32==FALSE)outword(num);
else outdword(num);
}
addESP-=num;
}
}
unsigned int initparamproc()
{
unsigned int typep=itok.flag,snum=0;
ITOK ostructadr=structadr;
strcpy(param,(char *)string);
nexttok();
switch(typep&f_typeproc){
case tp_cdecl:
case tp_stdcall:
snum=swapparam();
break;
case tp_pascal:
doparams();
break;
case tp_fastcall:
doregparams();
break;
}
// if(crec)printf("after doparams num=%08X\n",crec->recnumber);
if((typep&f_classproc)&&(!(typep&f_static))){
if((current_proc_type&f_static)&&structadr.sib==THIS_PARAM )return snum;
structadr=ostructadr;
if(structadr.sib==THIS_PARAM){
if(structadr.number==0){
op(0xff);
if(ESPloc&&am32){
int num;
num=localsize+addESP+4;
if(short_ok(num,TRUE)){
outword(0x2474);
op(num);
}
else{
outword(0x24B4);
outdword(num);
}
}
else outword(am32==FALSE?0x0476:0x0875);//push[ebp+4]
}
else{
int reg=GetRegister(1);
op(0x8B);
if(ESPloc&&am32){
int num;
num=localsize+addESP+4;
if(short_ok(num,TRUE)){
op(4+reg*8+64);
op(0x24);
op(num);
}
else{
op(4+reg*8+128);
op(0x24);
outdword(num);
}
}
else{
op((am32==FALSE?6:5)+reg*8+64);
op((am32==FALSE?4:8));//mov ESI,[ebp+4]
}
RegAddNum(reg);
op(0x50+reg); //push reg
warningreg(regs[am32][reg]);
}
}
else if(structadr.sib==THIS_REG){
if(structadr.number/*size*/!=0){
int reg=GetRegister(1);
if(reg==structadr.rm)RegAddNum(reg);
else{
if(am32==FALSE){
switch(structadr.rm){
case BX:
structadr.rm=7;
break;
case DI:
structadr.rm=5;
break;
case SI:
structadr.rm=4;
break;
case BP:
structadr.rm=6;
break;
default:
regBXDISIBPexpected();
}
structadr.sib=CODE16;
}
else structadr.sib=CODE32;
structadr.rm|=(structadr.number<128?rm_mod01:rm_mod10);
op(0x8d); //lea reg [reg2+num]
op(structadr.rm+reg*8);
outaddress(&structadr);
}
op(0x50+reg);
warningreg(regs[am32][reg]);
}
else op(0x50+structadr.rm);
}
else if(structadr.sib==THIS_NEW){
RunNew(structadr.number);
op(0x50);
}
else if(structadr.sib==THIS_ZEROSIZE){
outword(0x6a); //push 0
}
else{
// printf("post=%d\n",structadr.post);
if(structadr.post==LOCAL){
int reg=GetRegister(1);
structadr.post=0;
outseg(&structadr,2);
op(0x8d);
op(structadr.rm+reg*8);
outaddress(&structadr);
op(0x50+reg);
warningreg(regs[am32][reg]);
}
else{
if(strinf.bufstr){
int reg=GetRegister(1);
int newreg;
if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,reg))!=NOINREG){
if(newreg!=SKIPREG){
if(am32==FALSE&&newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt;
waralreadinitreg(regs[am32][reg],regs[am32][newreg]);
reg=newreg;
}
free(strinf.bufstr);
goto cont1;
}
noopt:
if(newreg=CheckMassiv(strinf.bufstr,strinf.size,reg)!=-1)reg=newreg;
cont1:
strinf.bufstr=NULL;
RegAddNum(reg);
op(0x50+reg);
}
else{
op(0x68);
if(structadr.post/*&&structadr.post!=USED_DIN_VAR*/)setwordpost(&structadr);
else if(FixUp)AddReloc();
if(am32==FALSE)outword((unsigned int)structadr.number);
else outdword(structadr.number);
}
}
}
snum+=(am32==FALSE?2:4);
addESP+=(am32==FALSE?2:4);
}
if(typep&f_far)op(0x0e); //push cs
return snum;
}
int doanyproc(int jumpsend)
{
unsigned int cloc,snum;
int returnvalue,dynamicindex;
int regs;
if(tok2==tk_colon){
preerror("dublication global label");
nexttok();
return 0;
}
cloc=(unsigned int)itok.number; /* get address or handle */
returnvalue=itok.rm;
regs=itok.post;
// printf("regs=%08X name=%s\n",regs,itok.name);
int flag=itok.flag;
if(itok.npointr)dopointerproc();
else{
if((itok.flag&f_inline)!=0&&(useinline==TRUE||(useinline==2&&optimizespeed))){
if(macros(tk_void)!=0)return(returnvalue);
}
dynamicindex=itok.segm;
// printf("%s %08X seg=%d\n",rec->recid/*itok.name*/,itok.flag,itok.segm);
if(itok.segm==DYNAMIC){
itok.segm=DYNAMIC_USED;
updatetree();
}
unsigned int oaddESP=addESP;
snum=initparamproc();
if((flag&f_typeproc)!=tp_cdecl){
snum=0;
addESP=oaddESP;
}
if(dynamicindex<NOT_DYNAMIC){ //фшэрьшўхёър яЁюЎхфєЁр
addacall(cloc,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR));
if(jumpsend)jumploc0();
else{
callloc0();
if(snum!=0)CorrectStack(snum);
}
}
else{
if(jumpsend)jumploc(cloc);
else{
callloc(cloc);
if(snum!=0)CorrectStack(snum);
}
}
}
#ifdef OPTVARCONST
if(flag&f_useidx)ClearLVIC();
else FreeGlobalConst();
#endif
clearregstat(regs);
return(returnvalue);
}
int doid(char uppercase,int expectedreturn)
{
int cnum;
if(tok2==tk_colon){ // if a label
#ifdef OPTVARCONST
ClearLVIC();
#endif
RestoreStack();
clearregstat();
cnum=FindOff((unsigned char *)itok.name,CS);
if(uppercase){
localrec *ptr=addlocalvar(itok.name,tk_number,outptr,TRUE);
if(FixUp)ptr->rec.flag=f_reloc;
}
else{
tok=tk_proc;
itok.rm=tk_void;
itok.number=outptr;
itok.segm=NOT_DYNAMIC;
itok.flag=0;
string[0]=0;
itok.type=tp_ucnovn;
addtotree(itok.name);
itok.rec->count=cnum;
}
nexttok(); // move past id
nexttok(); // move past :
return(tokens);
}
if(tok2==tk_openbracket){
if((cnum=CheckMacros())!=tokens)return cnum;
tobedefined(am32==FALSE?CALL_NEAR:CALL_32,expectedreturn);
cnum=posts-1;
param[0]=0;
int flag=itok.flag;
int exitproc=CheckExitProc();
unsigned int oaddESP=addESP;
if(itok.flag==tp_stdcall){
nexttok();
swapparam();
}
else{
nexttok();
if(uppercase)doregparams();
else doparams();
}
(postbuf+cnum)->loc=outptr+1;
callloc0(); /* produce CALL [#] */
clearregstat();
addESP=oaddESP;
#ifdef OPTVARCONST
if(flag&f_useidx)ClearLVIC();
else FreeGlobalConst();
#endif
retproc=exitproc;
return(expectedreturn);
}
thisundefined(itok.name);
return(tk_long);
}
int typesize(int vartype) // тючтЁр∙рхЄ ЁрчьхЁ т срщЄрї ъюфр тючтЁрЄр
{
switch(vartype){
case tk_char:
case tk_byte: return(1);
case tk_int:
case tk_word: return(2);
case tk_float:
case tk_dword:
case tk_long: return(4);
case tk_double:
case tk_qword: return 8;
}
return(0);
}
void FpuSt2Number()
{
op66(r32); //push EAX
op(0x50);
CheckInitBP();
fistp_stack();
RestoreBP();
fwait3();
op66(r32);
op(0x58); //pop EAX
if(cpu<3)cpu=3;
}
void FpuSt2QNumber()
{
op66(r32); //push EAX
op(0x50);
op66(r32); //push EAX
op(0x50);
CheckInitBP();
fistp_stack(4);
RestoreBP();
fwait3();
op66(r32);
op(0x58+EDX); //pop EAX
op66(r32);
op(0x58); //pop EAX
if(cpu<3)cpu=3;
}
void fwait3_4()
{
if(chip<4)op(0x9B);
}
void convert_returnvalue(int expectedreturn,int actualreturn)
{
if(expectedreturn==tk_void)return; //17.09.05 17:52
if(actualreturn==tk_void/*||expectedreturn==tk_void*/){
retvoid();
return;
}
switch(expectedreturn){
case tk_byte:
case tk_char:
case tk_word:
case tk_int:
if(actualreturn==tk_float||actualreturn==tk_double){
op66(r32);
op(0x50);
FloatToNumer(actualreturn==tk_float?0:4);
}
else if(actualreturn==tk_fpust)FpuSt2Number();
else if(expectedreturn==tk_word||expectedreturn==tk_int){
if(actualreturn==tk_char)cbw();
else if(actualreturn==tk_byte)xorAHAH();
}
break;
case tk_long:
case tk_dword:
switch(actualreturn){
case tk_char:
op66(r32);
op(0x0F); outword(0xC0BE); //MOVSX EAX,AL
break;
case tk_byte: /* MOVZX EAX,AL */
op66(r32);
op(0x0F); outword(0xC0B6);
break;
case tk_word: /* MOVZX EAX,AX */
op66(r32);
op(0x0F); outword(0xC0B7);
break;
case tk_int: /* MOVSX EAX,AX */
op66(r32);
op(0x0F); outword(0xC0BF);
break;
case tk_double:
case tk_fpust:
FpuSt2Number();
break;
// case tk_double:
case tk_float:
op66(r32);
op(0x50);
FloatToNumer(/*actualreturn==tk_float?0:4*/);
break;
}
if(cpu<3)cpu=3;
break;
case tk_qword:
switch(actualreturn){
case tk_char:
op66(r32);
op(0x0F); outword(0xC0BE); //MOVSX EAX,AL
cwdq(r32);
break;
case tk_byte: /* MOVZX EAX,AL */
op66(r32);
op(0x0F); outword(0xC0B6);
ZeroReg(EDX,r32);
break;
case tk_word: /* MOVZX EAX,AX */
op66(r32);
op(0x0F); outword(0xC0B7);
case tk_dword:
ZeroReg(EDX,r32);
break;
case tk_int: /* MOVSX EAX,AX */
op66(r32);
op(0x0F); outword(0xC0BF);
case tk_long:
cwdq(r32);
break;
case tk_fpust:
case tk_double:
FpuSt2QNumber();
break;
case tk_float:
op66(r32);
op(0x50);
FloatToNumer(actualreturn==tk_float?0:4);
cwdq(r32);
break;
}
if(cpu<3)cpu=3;
break;
case tk_fpust:
if(tok2==tk_semicolon)break;
switch(actualreturn){
case tk_char:
CheckInitBP();
cbw();
op66(r32);
outword(0xDF50); //push EAX
goto endfxld; //fild ss[bp-4]/[esp]
case tk_byte:
CheckInitBP();
xorAHAH();
op66(r32);
outword(0xDF50); //push EAX
goto endfxld; //fild ss[bp-4]/[esp]
case tk_word:
CheckInitBP();
op66(r16);
outword(0x6A); //push 0
op66(r16);
outword(0xDB50); //push AX
goto endfxld; //fild ss[bp-4]/[esp]
case tk_int:
CheckInitBP();
op66(r32);
outword(0xDF50); //push eax
goto endfxld; //fild ss[bp-4]/[esp]
case tk_dword:
CheckInitBP();
op66(r32); //push 0L
outword(0x6A);
op66(r32);
op(0x50); //push EAX
fildq_stack();
RestoreBP();
op66(r32);
op(0x58); //pop eax
op66(r32);
op(0x58); //pop eax
break;
case tk_long:
CheckInitBP();
op66(r32);
outword(0xDB50); //push EAX
goto endfxld; //fild ss[bp-4]/[esp]
case tk_float:
CheckInitBP();
op66(r32);
outword(0xd950); //push EAX
endfxld:
fld_stack(4+localsize);
RestoreBP();
op66(r32);
op(0x58); //pop eax
break;
case tk_qword:
// case tk_double:
CheckInitBP();
op66(r32);
op(0x50+EDX); //push EDX
op66(r32);
op(0x50); //push EAX
/* if(actualreturn==tk_double){
op(0xDD);
fld_stack(8+localsize);
}
else*/ fildq_stack();
RestoreBP();
op66(r32);
op(0x58); //pop eax
op66(r32);
op(0x58); //pop eax
break;
}
if(cpu<3)cpu=3;
break;
default:
// printf("expectedreturn=%d %s %d\n",expectedreturn,(startfileinfo+currentfileinfo)->filename,linenumber);
break;
}
}
int procdo(int expectedreturn)
{
int actualreturn;
char idflag=0;
switch(tok){
case tk_ID: idflag++;
case tk_id:
actualreturn=doid(idflag,expectedreturn);
break;
case tk_proc:
actualreturn=doanyproc();
break;
case tk_apiproc:
case tk_undefproc:
case tk_declare:
// if((actualreturn=doanyundefproc())==tk_void)actualreturn=expectedreturn;
actualreturn=doanyundefproc(); //17.09.05 17:56
break;
default: internalerror("Bad tok in procdo();"); break;
}
convert_returnvalue(expectedreturn,actualreturn);
return actualreturn;
}
/* +++++++++++++++++++++++ loops and ifs start ++++++++++++++++++++++++ */
void endcmpfloat()
{
fwait3();
outword(0xE0DF);//fstsw ax
op(0x9E);
RestoreBP();
}
int outcmp(int swapped,int ctok,ITOK *cstok,char *&cbuf,SINFO *cstr,int ctok2,ITOK *cstok2,char *&cbuf2,SINFO *cstr2,int typet)
{
unsigned char err=0;
int typef=0;
int vop=0;
long long lnumber;
unsigned int ofs;
int i,reg,reg1;
if(typet<r16)typet=r16;
switch(ctok){
case tk_reg64:
reg=cstok->number/256;
switch(ctok2){
case tk_reg64:
reg1=cstok2->number/256;
for(i=0;i<2;i++){
op66(r32);
op(0x39); //cmp reg,reg
op(0xC0+reg+reg1*8);
if(i==1)break;
outword(0x75);
ofs=outptr;
reg=cstok->number&255;
reg1=cstok2->number&255;
}
output[ofs-1]=outptr-ofs;
break;
case tk_number:
case tk_postnumber:
case tk_undefofs:
lnumber=cstok2->lnumber>>32;
for(i=0;i<2;i++){
op66(r32);
//яЁютхЁър эр тючьюцэюёЄ№ сюыхх ъюЁюЄъюую ъюфр
if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
short_ok(lnumber,TRUE)){
if(!lnumber){
op(0x85); //test reg,reg
op(0xc0+reg*9);
}
else{
op(0x83); //cmp reg,
op(0xF8+reg);
op(lnumber);
}
}
else{
if(reg==AX)op(0x3D);
else{
op(0x81);
op(0xF8+reg);
}
if(i==1){
if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
}
outdword(cstok2->number);
}
if(i==1)break;
outword(0x75);
ofs=outptr;
reg=cstok->number&255;
}
output[ofs-1]=outptr-ofs;
break;
default:
if(swapped)err=1;
else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
break;
}
break;
case tk_reg32:
case tk_reg:
switch(ctok2){
case tk_reg:
case tk_reg32:
if(ctok!=ctok2)err=1;
else{
op66(typet);
op(0x39); //cmp reg,reg
op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
}
break;
case tk_number:
if(cstok2->number==0&&(cstok2->flag&f_reloc)==0){
op66(typet);
op(0x85); //test reg,reg
op(0xc0+(unsigned int)cstok->number*9);
break;
}
case tk_postnumber:
case tk_undefofs:
op66(typet);
//яЁютхЁър эр тючьюцэюёЄ№ сюыхх ъюЁюЄъюую ъюфр
if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
short_ok(cstok2->number,ctok==tk_reg?FALSE:TRUE)){
op(0x83); //cmp reg,
op(0xF8+(unsigned int)cstok->number);
op(cstok2->number);
break;
}
if(cstok->number==AX)op(0x3D);
else{
op(0x81);
op(0xF8+(unsigned int)cstok->number);
}
if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
if(ctok==tk_reg)outword((unsigned int)cstok2->number);
else outdword(cstok2->number);
break;
default:
if(swapped)err=1;
else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
break;
}
break;
case tk_qwordvar:
cstok->number+=4;
compressoffset(cstok);
switch(ctok2){
case tk_postnumber:
case tk_number:
case tk_undefofs:
lnumber=cstok2->lnumber>>32;
CheckAllMassiv(cbuf,8,cstr,cstok);
for(i=0;i<2;i++){
op66(r32);
outseg(cstok,2);
//яЁютхЁър эр тючьюцэюёЄ№ сюыхх ъюЁюЄъюую ъюфр
if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
short_ok(lnumber,1)){
op(0x83);
op(0x38+cstok->rm);
outaddress(cstok);
op(lnumber);
}
else{
op(0x81);
op(0x38+cstok->rm);
outaddress(cstok);
if(i==1){
if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
}
outdword(lnumber);
}
if(i==1)break;
outword(0x75);
ofs=outptr;
cstok->number-=4;
compressoffset(cstok);
lnumber=cstok2->lnumber;
}
output[ofs-1]=outptr-ofs;
break;
case tk_reg64:
CheckAllMassiv(cbuf,8,cstr,cstok);
reg=cstok2->number/256;
for(i=0;i<2;i++){
op66(r32);
outseg(cstok,2);
op(0x39); /* CMP [word],AX */
op(cstok->rm+reg*8);
outaddress(cstok);
if(i==1)break;
reg=cstok2->number&255;
outword(0x75);
ofs=outptr;
cstok->number-=4;
compressoffset(cstok);
}
output[ofs-1]=outptr-ofs;
break;
default:
i=EAX|(EDX*256);
getintoreg64(i);
doregmath64(i);
CheckAllMassiv(cbuf,8,cstr,cstok);
reg=EDX;
for(i=0;i<2;i++){
op66(r32);
outseg(cstok,2);
op(0x39); /* CMP [word],AX */
op(cstok->rm+reg*8);
outaddress(cstok);
if(i==1)break;
reg=EAX;
outword(0x75);
ofs=outptr;
cstok->number-=4;
compressoffset(cstok);
}
output[ofs-1]=outptr-ofs;
break;
}
break;
case tk_intvar:
case tk_wordvar:
if(swapped&&typet==r32)typet=r16;
case tk_longvar:
case tk_dwordvar:
switch(ctok2){
case tk_reg32:
case tk_reg:
CheckAllMassiv(cbuf,typet,cstr,cstok);
op66(typet);
outseg(cstok,2);
op(0x39);
op((unsigned int)cstok2->number*8+cstok->rm);
outaddress(cstok);
break;
case tk_postnumber:
case tk_number:
case tk_undefofs:
CheckAllMassiv(cbuf,typet,cstr,cstok);
op66(typet);
outseg(cstok,2);
//яЁютхЁър эр тючьюцэюёЄ№ сюыхх ъюЁюЄъюую ъюфр
if((cstok2->flag&f_reloc)==0&&ctok2!=tk_postnumber&&ctok2!=tk_undefofs&&
short_ok(cstok2->number,typet/2-1)){
op(0x83);
op(0x38+cstok->rm);
outaddress(cstok);
op(cstok2->number);
break;
}
op(0x81);
op(0x38+cstok->rm);
outaddress(cstok);
if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
if(ctok2==tk_undefofs)AddUndefOff(2,cstok2->name);
if(typet==r16)outword((unsigned int)cstok2->number);
else outdword(cstok2->number);
break;
case tk_charvar:
case tk_intvar:
getinto_e_ax(1,ctok2,cstok2,cbuf2,cstr2,typet);
CheckAllMassiv(cbuf,typet,cstr,cstok);
op66(typet);
outseg(cstok,2);
op(0x39); /* CMP [word],AX */
op(cstok->rm);
outaddress(cstok);
break;
default:
getinto_e_ax(0,ctok2,cstok2,cbuf2,cstr2,typet);
// ClearReg(AX);
CheckAllMassiv(cbuf,typet,cstr,cstok);
op66(typet);
outseg(cstok,2);
op(0x39); /* CMP [word],AX */
op(cstok->rm);
outaddress(cstok);
break;
}
break;
case tk_number:
if(ctok2==tk_postnumber){
op(0xB8); /* MOV AX,# */
if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
if(am32==FALSE)outword((unsigned int)cstok->number);
else outdword(cstok->number);
op(0x3D); /* CMP AX,# */
(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
if(am32==FALSE)outword((unsigned int)cstok2->number);
else outdword(cstok2->number);
}
if(ctok2==tk_number){
if(cstok2->rm!=tk_float&&cstok->rm!=tk_float){
if((unsigned long)cstok2->number<256&&(unsigned long)cstok->number<256){
op(0xB0); //mov al,number
op(cstok->number);
op(0x3C); //cmp Al,number
op(cstok2->number);
}
else if((unsigned long)cstok2->number<65536&& cstok->number<65536){
op66(r16);
op(0xB8); /* MOV AX,# */
if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
outword((unsigned int)cstok->number);
op66(r16);
op(0x3D); /* CMP AX,# */
if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
outword((unsigned int)cstok2->number);
}
else{
op66(r32);
op(0xB8); /* MOV AX,# */
if((cstok->flag&f_reloc)!=0)AddReloc(cstok->segm);
outdword(cstok->number);
op66(r32);
op(0x3D); /* CMP AX,# */
if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
outdword(cstok2->number);
}
}
else{
op(0x55); //push bp
outword(0xe589);//mov bp,sp
op66(r32);
if(short_ok(cstok->number,TRUE)){ //push num
op(0x6A);
op(cstok->number);
}
else{
op(0x68);
outdword(cstok->number);
}
op66(r32);
if(short_ok(cstok2->number,TRUE)){ //push num
op(0x6A);
op(cstok2->number);
}
else{
op(0x68);
outdword(cstok2->number);
}
outword(am32==FALSE?0x46d9:0x45d9);
op(0xfC);//fld ssdword[bp-4]
op(0xD8);
outword(0xF85e - am32); //fcomp [bp-8]
endcmpfloat();
}
}
else{
if(swapped)err=1;
else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
}
break;
case tk_postnumber:
if(ctok2==tk_number||ctok2==tk_postnumber){
op(0xB8); /* MOV AX,# */
(cstok->flag&f_extern)==0?setwordpost(cstok):setwordext(&cstok->number);
if(am32==FALSE)outword((unsigned int)cstok->number);
else outdword(cstok->number);
op(0x3D); /* CMP AX,# */
if(ctok2==tk_postnumber)(cstok2->flag&f_extern)==0?setwordpost(cstok2):setwordext(&cstok2->number);
else if((cstok2->flag&f_reloc)!=0)AddReloc(cstok2->segm);
if(am32==FALSE)outword((unsigned int)cstok2->number);
else outdword(cstok2->number);
}
else{
if(swapped)err=1;
else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
}
break;
case tk_charvar:
case tk_bytevar:
switch(ctok2){
case tk_number:
CheckAllMassiv(cbuf,1,cstr,cstok);
outseg(cstok,2);
op(0x80); /* CMP [byte],# */
op(0x38+cstok->rm);
outaddress(cstok);
op((unsigned int)cstok2->number);
break;
case tk_reg:
case tk_reg32:
if(cstok2->number>3)goto defchar;
case tk_beg:
CheckAllMassiv(cbuf,1,cstr,cstok);
outseg(cstok,2);
op(0x38); /* CMP [byte],beg */
op((unsigned int)cstok2->number*8+cstok->rm);
outaddress(cstok);
break;
default:
defchar:
getintoal(ctok2,cstok2,cbuf2,cstr2);
CheckAllMassiv(cbuf,1,cstr,cstok);
outseg(cstok,2);
op(0x38); /* CMP [byte],AL */
op(cstok->rm);
outaddress(cstok);
break;
}
break;
case tk_beg:
switch(ctok2){
case tk_number:
if(cstok2->number==0){
op(0x84); //test beg,beg
op(0xc0+(unsigned int)cstok->number*9);
break;
}
if((unsigned int)cstok->number==AL)op(0x3C);
else{
op(0x80);
op(0xF8+(unsigned int)cstok->number);
}
op((unsigned int)cstok2->number);
break;
case tk_beg:
op(0x38);
op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
break;
case tk_reg:
if((unsigned int)cstok2->number<=BX){ /* CMP beg,beg */
op(0x38);
op(0xC0+(unsigned int)cstok->number+(unsigned int)cstok2->number*8);
}
else{
op66(r16);
op(0x89); /* MOV AX,reg */
op(0xC0+(unsigned int)cstok2->number*8);
op(0x38); /* CMP beg,AL */
op(0xC0+(unsigned int)cstok->number);
}
break;
default:
if(swapped)err=1;
else return(outcmp(1,ctok2,cstok2,cbuf2,cstr2,ctok,cstok,cbuf,cstr,typet));
break;
}
break;
case tk_doublevar:
vop=4;
goto cont_float;
case tk_fpust:
typef++;
if(cstok->type==tp_modif)typef++;
else{
if(cstok->number!=0){
op(0xd9); //fld st(x)
op(0xC0+cstok->number);
typef++;
}
}
case tk_floatvar:
cont_float:
switch(ctok2){
case tk_beg:
CheckInitBP();
switch(cstok2->rm){
case tk_char:
case tk_int:
case tk_long:
outword(0xBE0F); /* MOVSX AX,beg */
op(0xC0+(unsigned int)cstok2->number);
break;
default:
if((optimizespeed&&chip>3&&chip<7)||cstok2->number==AL){
xorAHAH();
if(cstok2->number!=AL){
op(0x88);
op(0xC0+cstok2->number*8); //mov al,beg
}
}
else{
outword(0xB60F); // MOVZX AX,beg
op(0xC0+(unsigned int)cstok2->number);
}
break;
}
outword(0xDF50); //push AX
fld_stack(2+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op(0x58); // pop EAX
endcmpfloat();
swapped=1;
break;
case tk_reg:
CheckInitBP();
op66(r32);
switch(cstok2->rm){
case tk_char:
case tk_int:
case tk_long:
outword(0xBF0F); /* MOVSX EAX,reg */
break;
default:
if(optimizespeed&&chip>3&&chip<7&&cstok2->number!=AX){
outword(0xC031); // xor EAX,EAX
op66(r16);
op(0x8B);
}
else outword(0xB70F); // MOVZX EAX,reg
break;
}
op(0xC0+(unsigned int)cstok2->number);
op66(r32);
outword(0xDB50); //push EAX
fld_stack(4+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op66(r32);
op(0x58); // pop EAX
endcmpfloat();
swapped=1;
break;
case tk_reg32:
CheckInitBP();
if(cstok2->rm==tk_float){
op66(r32);
op(0x50+(unsigned int)cstok2->number); //push reg32
op(0xd9);
fld_stack(4+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op66(r32);
op(0x58); // pop EAX
}
else{
if(cstok2->rm!=tk_char&&cstok2->rm!=tk_int&&cstok2->rm!=tk_long){
typet=tk_word;
op66(r32);
outword(0x6a); //$push 0
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
}
op66(r32);
op(0x50+cstok2->number); //push reg32
if(typet!=r16)fildq_stack();
else{
op(0xdb);
fld_stack(4+localsize);
}
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
if(typet!=r16){
if(optimizespeed||am32==FALSE){
outword(0xC483);
op(8);
}
else{
op(0x58); // pop EAX
op(0x58); // pop EAX
}
}
else{
op66(r32);
op(0x58); // pop EAX
}
}
endcmpfloat();
swapped=1;
break;
case tk_charvar:
CheckAllMassiv(cbuf2,1,cstr2,cstok2);
outseg(cstok2,3); /* MOVSX AX,[charvar] */
outword(0xBE0F); op(cstok2->rm);
outaddress(cstok2);
CheckInitBP();
outword(0xdf50); //push ax
fld_stack(2+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op(0x58); // pop EAX
endcmpfloat();
swapped=1;
break;
case tk_intvar:
CheckAllMassiv(cbuf2,2,cstr2,cstok2);
outseg(cstok2,2);
if(typef){
op(0xDE); //ficomp var2
op(cstok2->rm+0x08+typef*8);
outaddress(cstok2);
}
else{
op(0xdf); //fild var
op(cstok2->rm);
outaddress(cstok2);
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
swapped=1;
}
fwait3_4();
outword(0xE0DF);//fstsw ax
op(0x9E);
break;
case tk_bytevar:
CheckAllMassiv(cbuf2,1,cstr2,cstok2);
if(optimizespeed&&chip>3&&chip<7){
outword(0xC031);
outseg(cstok2,2);
op(0x8A);
}
else{
outseg(cstok2,3);
outword(0xB60F);
}
op(cstok2->rm); // MOVZX regL,[byte]
outaddress(cstok2);
CheckInitBP();
outword(0xDF50); //push ax
fld_stack(2+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op(0x58); // pop EAX
endcmpfloat();
swapped=1;
break;
case tk_wordvar:
CheckInitBP();
op66(r16);
outword(0x6a); //push 0
CheckAllMassiv(cbuf2,2,cstr2,cstok2);
op66(r16);
outseg(cstok2,2); //push var
op(0xFF);
op(cstok2->rm+0x30);
outaddress(cstok2);
op(0xDB);
fld_stack(4+localsize);
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=4;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
op66(r32);
op(0x58); // pop EAX
endcmpfloat();
swapped=1;
break;
case tk_dwordvar:
CheckInitBP();
op66(r32); //push 0L
outword(0x6a);
CheckAllMassiv(cbuf2,4,cstr2,cstok2);
op66(r32); //push var
outseg(cstok2,2);
op(0xFF);
op(cstok2->rm+0x30);
outaddress(cstok2);
fildq_stack();
if(typef==2)outword(0xD9DE); //FCOMPP
else if(typef==1)outword(0xD9D8); //FCOMP
else{
if(ESPloc&&am32&&cstok->segm==SS)cstok->number+=8;
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
}
if(optimizespeed||am32==FALSE){
outword(0xC483);
op(8);
}
else{
op(0x58); // pop EAX
op(0x58); // pop EAX
}
endcmpfloat();
swapped=1;
break;
case tk_longvar:
CheckAllMassiv(cbuf2,4,cstr2,cstok2);
outseg(cstok2,2);
if(typef){
op(0xDA); //ficomp var2
op(cstok2->rm+0x08+typef*8);
outaddress(cstok2);
}
else{
op(0xdb); //fild var
op(cstok2->rm);
outaddress(cstok2);
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fcomp var
op(0xd8+vop);
op(cstok->rm+0x18);
outaddress(cstok);
swapped=1;
}
endcmpfloat();
break;
case tk_number:
if(!typef){
CheckAllMassiv(cbuf,4,cstr,cstok);
outseg(cstok,2); //fld val
op(0xd9);
op(cstok->rm);
outaddress(cstok);
}
if(cstok2->rm!=tk_double&&cstok2->rm!=tk_float){
cstok2->dnumber=cstok2->lnumber;
cstok2->rm=tk_double;
}
else if(vop==4&&cstok2->rm==tk_float){
cstok2->dnumber=cstok2->fnumber;
cstok2->rm=tk_double;
}
if(am32&&(cstok2->rm==tk_float&&cstok2->fnumber==0.0)||
(cstok2->rm==tk_double&&cstok2->dnumber==0.0)||cstok2->lnumber==0){
outword(0xe4d9); //ftst
if(typef!=1)outword(0xC0DD); //ffree
}
else{
op66(r32);
int rm;
rm=(am32==FALSE?0x1eD8:0x1DD8);
if(typef==1)rm-=0x800;
if(cstok2->rm==tk_double||vop==4)rm+=4;
outword(rm); //fcom(p)
AddFloatConst(cstok2->lnumber,cstok2->rm);
outword(0);
if(am32)outword(0);
}
endcmpfloat();
break;
case tk_floatvar:
if(!typef){
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fld val
op(0xd9+vop);
op(cstok->rm);
outaddress(cstok);
}
CheckAllMassiv(cbuf2,4,cstr2,cstok2);
outseg(cstok2,2); //fcomp var
op(0xd8);
op(cstok2->rm+(typef==1?0x10:0x18));
outaddress(cstok2);
endcmpfloat();
break;
case tk_doublevar:
if(!typef){
CheckAllMassiv(cbuf,4+vop,cstr,cstok);
outseg(cstok,2); //fld val