0,0 → 1,10266 |
#define _TOKC_ |
|
#include <fcntl.h> /* O_ constant definitions */ |
#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 |
op(0xd9+vop); |
op(cstok->rm); |
outaddress(cstok); |
} |
CheckAllMassiv(cbuf2,8,cstr2,cstok2); |
outseg(cstok2,2); //fcomp var |
op(0xd8+4); |
op(cstok2->rm+(typef==1?0x10:0x18)); |
outaddress(cstok2); |
endcmpfloat(); |
break; |
case tk_fpust: |
if(typef==2){ //fcomp |
if(chip>=7){ //fcomip |
op(0xDF); |
op(0xF0+cstok2->number+1); |
swapped=1; |
break; |
} |
op(0xD8); |
op(0xD8+cstok2->number+1); |
} |
else if(typef==1){ //fcom |
if(chip>=7){ //fcomi |
op(0xDB); |
op(0xF0+cstok2->number); |
swapped=1; |
break; |
} |
op(0xD8); |
op(0xD0+cstok2->number); |
} |
else{ |
if(cstok2->type!=tp_modif){ |
op(0xd9); //fld st(x) |
op(0xC0+cstok2->number); |
} |
CheckAllMassiv(cbuf,4+vop,cstr,cstok); |
outseg(cstok,2); //fcomp var |
op(0xd8+vop); |
op(cstok->rm+0x18); |
outaddress(cstok); |
} |
endcmpfloat(); |
swapped=1; |
break; |
default: |
err=1; |
break; |
} |
break; |
default: err=1; break; |
} |
if(err)preerror("unable to create comparison, check restrictions"); |
return(swapped); |
} |
|
int CheckCompareTok(int reg) |
{ |
int comparetok=tk_equalto; |
if(itok.type==tp_compare)comparetok=tok; |
else unknowncompop(); |
getoperand(reg); |
return comparetok; |
} |
|
int typenumber(int vtok) |
{ |
switch(vtok){ |
case tk_char: |
case tk_beg: |
case tk_byte: |
return tk_byte; |
case tk_int: |
case tk_reg: |
case tk_word: |
return tk_word; |
case tk_reg64: |
case tk_qword: |
return tk_qword; |
case tk_floatvar: |
case tk_float: |
return tk_float; |
case tk_doublevar: |
case tk_double: |
return tk_double; |
} |
return tk_dword; |
} |
|
#ifdef OPTVARCONST |
int constructcompare(int invertflag,unsigned int startloc,LVIC *comconst) |
#else |
int constructcompare(int invertflag,unsigned int startloc) |
#endif |
/* build cmp for IF, if and do {} while */ |
{ |
int comparetok=0,jumptype,vartype=tokens,notflag=FALSE; |
int ittok,ittok2=tokens,type2=tokens;//,retcompare=tokens; |
int razr=r_undef; |
char *ibuf,*ibuf2; |
ITOK htok,htok2; |
SINFO hstr,hstr2; |
int preg=(am32==TRUE?EAX:SI); |
int use_cxz=0; |
char *ofsstr=NULL,*ofsstr2=NULL; |
int usereg=-1; |
int usereg2=-1; |
|
//////04.10.04 13:45 |
int bracket=0; |
unsigned char oinline=useinline; |
useinline=0; |
do{ |
nexttok(); |
// printf("tok=%d tok2=%d\n",tok,tok2); |
if(tok==tk_openbracket)bracket++; |
if(tok==tk_not)notflag=(notflag+1)%2; |
}while(tok2==tk_openbracket||tok2==tk_not); |
if(bracket==0)expected('('); |
///////////////// |
|
setzeroflag=FALSE; |
ofsstr=GetLecsem(tk_closebracket,tk_eof,tp_compare); |
getoperand(); //NEW 04.10.04 13:45 |
if(tok==tk_openbracket){ |
bracket++; |
getoperand(); |
} |
if(tok==tk_not){ |
notflag=(notflag+1)%2; |
getoperand(); |
} |
switch(tok){ |
case tk_closebracket: |
useinline=oinline; |
getoperand(); |
return voidcompr; |
case tk_asm: |
if(tok2==tk_openbrace){ |
nexttok(); |
type2=tok; |
} |
case tk_dollar: |
nexttok(); |
case tk_idasm: |
if(stricmp(itok.name,"test")==0){ |
if(iTest(1)==FALSE)InvOperComp(); |
ittok=0x75; |
if(type2==tk_openbrace)expecting(tk_closebrace); |
goto endcomp; |
} |
else preerror("Only 'TEST' possible use in compare"); |
break; |
case tk_qword: |
case tk_double: |
razr+=4; |
case tk_beg: |
case tk_reg32: |
case tk_reg: vartype=tok; break; |
case tk_float: |
case tk_long: |
case tk_dword: |
razr+=2; |
case tk_int: |
case tk_word: |
razr++; |
case tk_char: |
case tk_byte: |
razr++; |
vartype=tok; |
getoperand(); |
if(tok==tk_closebracket&&bracket>1){ |
bracket--; |
getoperand(); |
} |
break; |
case tk_undefproc: |
case tk_declare: |
// if(itok.rm==tk_void)itok.rm=(am32==FALSE?tk_word:tk_dword); |
case tk_proc: |
case tk_apiproc: |
vartype=itok.rm; |
if(vartype==tokens)vartype=(am32==FALSE?tk_word:tk_dword); |
else if(vartype==tk_void&&(itok.flag&f_retproc)==0){ |
retvoid(); |
vartype=itok.rm=(am32==FALSE?tk_word:tk_dword); |
} |
if(ofsstr){ |
free(ofsstr); |
ofsstr=NULL; |
} |
break; |
case tk_bytevar: vartype=tk_byte; break; |
case tk_charvar: vartype=tk_char; break; |
case tk_intvar: vartype=tk_int; break; |
case tk_wordvar: vartype=tk_word; break; |
case tk_dwordvar: vartype=tk_dword; break; |
case tk_longvar: vartype=tk_long; break; |
case tk_floatvar: vartype=tk_float; break; |
case tk_qwordvar: vartype=tk_qword; break; |
case tk_fpust: |
case tk_doublevar: vartype=tk_double; break; |
case tk_bits: |
int i; |
i=itok.bit.ofs+itok.bit.siz; |
if(i<=64){ |
vartype=tk_dword; |
razr=r64; |
} |
if(i<=32){ |
vartype=tk_dword; |
razr=r32; |
} |
if(i<=16){ |
vartype=tk_word; |
razr=r16; |
} |
if(i<=8){ |
vartype=tk_byte; |
razr=r8; |
} |
break; |
case tk_at: |
if(ofsstr){ |
free(ofsstr); |
ofsstr=NULL; |
} |
nexttok(); |
if(itok.flag&f_retproc){ |
comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
// notflag=(notflag==FALSE?TRUE:FALSE); |
vartype=tk_ID; |
ittok2=macros(vartype); |
if(tok2==tk_closebracket){ |
nexttok(); |
ittok=0x70+comparetok-tk_overflowflag; |
goto endcomp; |
} |
if(ittok2==0){ |
vartype=itok.rm; |
break; |
} |
goto mac1; |
} |
if((itok.flag&f_typeproc)==tp_fastcall&&itok.segm!=NOT_DYNAMIC)vartype=itok.rm; |
else vartype=tk_ID; |
if((ittok2=macros(vartype))==0){ |
vartype=itok.rm; |
break; |
} |
mac1: |
vartype=ittok2; |
switch(vartype){ |
case tk_byte: |
case tk_char: tok=tk_beg; break; |
case tk_int: |
case tk_word: tok=tk_reg; break; |
case tk_float: |
case tk_dword: |
case tk_long: tok=tk_reg32; break; |
case tk_double: |
case tk_qword: tok=tk_reg64; break; |
default: |
preerror("Macro has a return type of void"); |
tok=tk_reg; |
vartype=tk_word; |
break; |
} |
itok.number=AX; // or AL or EAX |
break; |
default: |
if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ |
ittok=0x70+tok-tk_overflowflag; |
nexttok(); |
if(tok!=tk_closebracket&&(tok==tk_oror||tok==tk_andand||tok==tk_notequal||tok==tk_equalto)){ |
int oper; |
int oper2; |
oper=tok; |
nexttok(); |
ittok^=notflag; |
notflag=0; |
if(tok==tk_not){ |
notflag=TRUE; |
nexttok(); |
} |
if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ |
ittok-=0x70; |
ittok2=tok-tk_overflowflag; |
ittok2^=notflag; |
notflag=0; |
nexttok(); |
switch(oper){ |
case tk_oror: |
if((ittok==2&&ittok2==4)||(ittok==4&&ittok2==2))ittok=6; |
else if(ittok==4&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1; |
else unknowncompop(); |
break; |
case tk_andand: |
if((ittok==3&&ittok2==5)||(ittok==5&&ittok2==3))ittok=7; |
else if(ittok==5&&(ittok2==8||ittok2==0))ittok=(ittok|ittok2)+1; |
else unknowncompop(); |
break; |
case tk_notequal: |
if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=12; |
else unknowncompop(); |
break; |
case tk_equalto: |
if((ittok==8&&ittok2==0)||(ittok==0&&ittok2==8))ittok=13; |
else unknowncompop(); |
break; |
} |
if(tok!=tk_closebracket&&(tok==tk_notequal||tok==tk_equalto)){ |
oper2=tok; |
nexttok(); |
if(tok==tk_not){ |
notflag=TRUE; |
nexttok(); |
} |
if((tok>=tk_overflowflag)&&(tok<=tk_plusflag)){ |
ittok2=tok-tk_overflowflag; |
ittok2^=notflag; |
notflag=0; |
nexttok(); |
if(oper2==tk_notequal){ |
if(oper==tk_oror&&((ittok==5&&ittok2==8)||(ittok==13&&ittok2==0)))ittok=14; |
else unknowncompop(); |
} |
else{ |
if(oper==tk_andand&&((ittok==6&&ittok2==8)||(ittok==14&&ittok2==0)))ittok=15; |
else unknowncompop(); |
} |
} |
else unknowncompop(); |
} |
} |
else unknowncompop(); |
ittok+=0x70; |
} |
goto endcomp; |
} |
vartype=(am32==FALSE?tk_word:tk_dword); |
break; |
} |
CheckMinusNum(); |
if(itok2.type!=tp_compare&&tok2!=tk_closebracket){ //ñëîæíûé îïåðàíä |
if(ofsstr){ |
int retreg; |
razr=getrazr(vartype); |
if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ |
GetEndLex(tk_closebracket,tk_semicolon,tp_compare); |
nexttok(); |
if(razr==r16)ittok=tk_reg; |
else if(razr==r32)ittok=tk_reg32; |
else ittok=tk_beg; |
usereg=htok.number=retreg==SKIPREG?AX:retreg; |
goto nn1; |
} |
} |
comparetok=0;//èñïîëüçóåòñÿ âðåìåííî íå ïîñìûñëó |
ittok=tok; |
htok=itok; |
ibuf=NULL; |
hstr.bufstr=NULL; |
ittok2=tok2; |
preg=BX; |
switch(tok2){ |
case tk_assign: |
case tk_plusplus: |
case tk_minusminus: |
case tk_divequals: |
case tk_minusequals: |
case tk_multequals: |
case tk_plusequals: |
switch(tok){ |
case tk_charvar: comparetok=1; |
case tk_bytevar: |
if((comparetok=dobytevar(comparetok,0))==tk_reg||comparetok==tk_beg){ |
usereg=htok.number=AX; |
ittok=tk_beg; |
} |
break; |
case tk_intvar: comparetok=1; |
case tk_wordvar: |
if((comparetok=do_d_wordvar(comparetok,r16,0))==tk_reg){ |
usereg=htok.number=AX; |
ittok=tk_reg; |
} |
break; |
case tk_longvar: comparetok=1; |
case tk_dwordvar: |
if((comparetok=do_d_wordvar(comparetok,r32,0))==tk_reg32){ |
usereg=htok.number=AX; |
ittok=tk_reg32; |
} |
break; |
case tk_floatvar: |
if(dofloatvar(0,tk_fpust,0)==tk_fpust){ |
ittok=tk_fpust; |
htok.type=tp_modif; |
} |
break; |
case tk_qwordvar: |
if((comparetok=doqwordvar(0))==tk_reg64){ |
ittok=tk_reg64; |
usereg=htok.number=EAX|(EDX*256); |
} |
break; |
case tk_reg64: |
usereg=itok.number; |
getintoreg64(itok.number); |
doregmath64(itok.number); |
comparetok=tk_reg64; |
break; |
case tk_reg32: |
usereg=itok.number; |
comparetok=doreg_32((unsigned int)itok.number,r32,0); |
// printf("comparetok=%d\n",comparetok); |
break; |
case tk_reg: |
usereg=itok.number; |
comparetok=doreg_32((unsigned int)itok.number,r16,0); |
break; |
case tk_beg: |
usereg=itok.number; |
comparetok=dobeg((unsigned int)itok.number,0); |
break; |
default: InvOperComp(); break; |
} |
if(ittok<tk_floatvar&&(!(comparetok>=tk_overflowflag&&comparetok<=tk_plusflag))){ |
if(ittok2!=tk_assign&&ittok2!=tk_divequals&&ittok2!=tk_multequals){ |
if(tok==tk_closebracket){ |
ittok=0x75; |
goto endcomp; |
} |
if(tok2==tk_number&&itok2.number==0){ |
if((ittok2==tk_plusplus||ittok2==tk_minusminus)&& |
tok!=tk_notequal&&tok!=tk_equalto)break; |
comparetok=CheckCompareTok(BX); |
nexttok(); |
goto createopcode; |
} |
} |
} |
break; |
default: |
switch(vartype){ |
case tk_int: comparetok=do_e_axmath(1,r16,&ofsstr); ittok=tk_reg; break; |
case tk_reg: |
case tk_word: comparetok=do_e_axmath(0,r16,&ofsstr); ittok=tk_reg; break; |
case tk_char: comparetok=doalmath(1,&ofsstr); ittok=tk_beg; break; |
case tk_beg: |
case tk_byte: comparetok=doalmath(0,&ofsstr); ittok=tk_beg; break; |
case tk_long: comparetok=do_e_axmath(1,r32,&ofsstr); ittok=tk_reg32; break; |
case tk_reg32: |
case tk_dword: |
comparetok=do_e_axmath(0,r32,&ofsstr); |
ittok=tk_reg32; |
break; |
case tk_qword: |
usereg=htok.number=EAX|(EDX*256); |
getintoreg64(usereg); |
doregmath64(usereg); |
comparetok=ittok=tk_reg64; |
break; |
case tk_float: |
doeaxfloatmath(tk_fpust); |
ittok=tk_fpust; |
htok.type=tp_modif; |
break; |
default: |
if(itok.flag&f_retproc){ |
comparetok=(itok.flag&f_retproc)/256+tk_overflowflag-1; |
// printf("tok=%d flag=%08X comparetok=%u %s\n",tok,itok.flag,comparetok,itok.name); |
// notflag=(notflag==FALSE?TRUE:FALSE); |
switch(tok){ |
case tk_undefproc: |
case tk_declare: |
case tk_apiproc: |
doanyundefproc(); |
break; |
case tk_proc: |
doanyproc(); |
break; |
} |
nexttok(); |
if(tok!=tk_closebracket){ |
retvoid(); |
do{ |
nexttok(); |
}while(tok!=tk_closebracket); |
} |
} |
else{ |
internalerror("Bad vartype value in constructcompare();"); |
tok=tk_reg; break; |
} |
} |
if(ittok!=tk_reg64)usereg=htok.number=AX; // same value as AL and EAX |
} |
RestoreStack(); |
} |
else{ |
#ifdef OPTVARCONST |
CheckConstVar3(&tok,&itok,razr); |
#endif |
if(tok>=tk_charvar&&tok<=tk_doublevar){ |
switch(vartype){ |
case tk_int: tok=tk_intvar; break; |
case tk_word: tok=tk_wordvar; break; |
case tk_char: tok=tk_charvar; break; |
case tk_byte: tok=tk_bytevar; break; |
case tk_long: tok=tk_longvar; break; |
case tk_dword: tok=tk_dwordvar; break; |
case tk_float: tok=tk_floatvar; break; |
case tk_qword: tok=tk_qwordvar; break; |
case tk_double: tok=tk_doublevar; break; |
} |
} |
else if(tok==tk_number){ |
if(tok2==tk_closebracket){ |
invertflag=(itok.number==0?zerocompr:voidcompr); |
nexttok(); |
getoperand(); |
useinline=oinline; |
return invertflag; |
} |
if(itok.rm==tk_float)vartype=tk_float; |
} |
else if(tok==tk_bits){ |
bits2reg(AX,razr); |
switch(razr){ |
case r64: |
case r32: |
tok=tk_reg32; |
break; |
case r16: |
tok=tk_reg; |
break; |
case r8: |
tok=tk_beg; |
break; |
} |
itok.number=0; |
} |
if(tok==tk_beg||tok==tk_reg||tok==tk_reg32)itok.rm=vartype; //òèï ñîäåðæèìîãî â reg32 |
ittok=tok; |
htok=itok; |
ibuf=bufrm; |
bufrm=NULL; |
hstr=strinf; |
strinf.bufstr=NULL; |
nexttok(); |
} |
nn1: |
if(razr==r_undef){ |
switch(vartype){ |
case tk_qword: |
case tk_double: |
razr+=4; |
case tk_long: |
case tk_dword: |
case tk_float: |
case tk_reg32: |
razr+=2; |
case tk_int: |
case tk_word: |
case tk_reg: |
razr++; |
case tk_char: |
case tk_byte: |
case tk_beg: |
razr++; |
} |
} |
if(tok!=tk_closebracket){ //ñðàâíåíèå |
ofsstr2=GetLecsem(tk_closebracket); |
comparetok=CheckCompareTok(preg); |
if(tok>=tk_char&&tok<=tk_double){ |
type2=tok; |
if(ofsstr2)free(ofsstr2); |
ofsstr2=GetLecsem(tk_closebracket); |
getoperand(preg); |
} |
if(tok==tk_minus){ |
if(CheckMinusNum()==FALSE){ |
preerror("only negative of constants valid within compairsons"); |
nexttok(); |
} |
} |
#ifdef OPTVARCONST |
CheckConstVar3(&tok,&itok,razr); |
#endif |
if(tok==tk_number){ |
switch(vartype){ |
case tk_long: |
case tk_int: |
case tk_char: |
htok2.number=doconstlongmath(); |
itok.flag=(unsigned char)postnumflag; |
break; |
case tk_dword: |
case tk_reg32: |
case tk_beg: |
case tk_reg: |
case tk_word: |
case tk_byte: |
htok2.number=doconstdwordmath(); |
itok.flag=(unsigned char)postnumflag; |
break; |
case tk_float: |
htok2.number=doconstfloatmath(); |
break; |
case tk_reg64: |
case tk_qword: |
htok2.lnumber=doconstqwordmath(); |
itok.flag=(unsigned char)postnumflag; |
break; |
case tk_double: |
htok2.lnumber=doconstdoublemath(); |
break; |
} |
htok2.rm=typenumber(vartype); |
ittok2=tk_number; |
htok2.flag=itok.flag; |
} |
else{ |
if(ittok>=tk_charvar&&ittok<=tk_doublevar&&(tok==tk_proc||tok==tk_id|| |
tok==tk_undefproc||tok==tk_declare||tok==tk_apiproc||tok==tk_ID|| |
itok2.type==tp_opperand||(tok>=tk_charvar&&tok<=tk_doublevar))){ |
if(ofsstr2){ |
int retreg; |
razr=getrazr(vartype); |
if((retreg=CheckIDZReg(ofsstr2,AX,razr))!=NOINREG){ |
GetEndLex(tk_closebracket); |
usereg2=retreg==SKIPREG?AX:retreg; |
if(razr==r16)ittok2=tk_reg; |
else if(razr==r32)ittok2=tk_reg32; |
else ittok2=tk_beg; |
htok2.number=usereg2; |
nexttok(); |
goto en2; |
} |
} |
int sign=0; |
switch(ittok){ |
case tk_charvar: sign=1; |
case tk_bytevar: |
doalmath(sign,&ofsstr2); |
usereg2=htok2.number=AX; |
ittok2=tk_beg; |
break; |
case tk_intvar: sign=1; |
case tk_wordvar: |
do_e_axmath(sign,r16,&ofsstr2); |
usereg2=htok2.number=AX; |
ittok2=tk_reg; |
break; |
case tk_longvar: sign=1; |
case tk_dwordvar: |
do_e_axmath(sign,r32,&ofsstr2); |
usereg2=htok2.number=AX; |
ittok2=tk_reg32; |
break; |
case tk_floatvar: |
doeaxfloatmath(tk_fpust); |
ittok2=tk_fpust; |
htok2.type=tp_modif; |
htok2.number=0; |
ClearReg(AX); |
break; |
case tk_doublevar: |
doeaxfloatmath(tk_fpust,0,4); |
ittok2=tk_fpust; |
htok2.type=tp_modif; |
htok2.number=0; |
ClearReg(AX); |
break; |
case tk_qwordvar: |
usereg2=htok2.number=EAX|(EDX*256); |
getintoreg64(usereg2); |
doregmath64(usereg2); |
ittok2=tk_reg64; |
ClearReg(AX); |
ClearReg(DX); |
break; |
} |
} |
else{ |
if(tok==tk_bits){ |
int i=itok.bit.ofs+itok.bit.siz; |
int vops; |
if(i<=64)vops=r64; |
if(i<=32)vops=r32; |
if(i<=16)vops=r16; |
if(i<=8)vops=r8; |
if(vops<razr)vops=razr; |
i=AX; |
if((ittok==tk_reg32||ittok==tk_reg||ittok==tk_beg)&&htok.number==0)i=CX; |
bits2reg(i,vops); |
switch(razr){ |
case r64: |
case r32: |
tok=tk_reg32; |
break; |
case r16: |
tok=tk_reg; |
break; |
case r8: |
tok=tk_beg; |
break; |
} |
itok.number=i; |
ClearReg(i); |
} |
switch(tok){ |
case tk_beg: |
case tk_reg: |
case tk_reg32: |
itok.rm=type2; //òèï ñîäåðæèìîãî â reg32 |
if((ittok==tk_reg32||ittok==tk_reg||ittok==tk_beg)&& |
htok.number==itok.number)preerror("Comparison two identical registers"); |
break; |
} |
int next=TRUE; |
int sign=0; |
if(ittok==tk_reg32){ |
if(ofsstr2){ |
int retreg; |
int treg; |
treg=(htok.number==0?DX:AX); |
razr=r32; |
if((retreg=CheckIDZReg(ofsstr2,treg,r32))!=NOINREG){ |
if(retreg==SKIPREG)retreg=treg; |
if(retreg!=htok.number){ |
GetEndLex(tk_closebracket); |
ittok2=tk_reg32; |
htok2.number=usereg2=retreg; |
nexttok(); |
goto en2; |
} |
} |
} |
switch(tok){ |
case tk_intvar: |
sign=1; |
case tk_wordvar: |
if(htok.number!=0){ |
do_e_axmath(sign,r32,&ofsstr2); |
usereg2=itok.number=0; |
} |
else{ |
getintoreg_32(DX,r32,sign,&ofsstr2); |
usereg2=itok.number=DX; |
} |
warningreg(regs[1][itok.number]); |
next=FALSE; |
ittok2=tk_reg32; |
htok2=itok; |
} |
} |
if(next){ |
ittok2=tok; |
htok2=itok; |
ibuf2=bufrm; |
bufrm=NULL; |
hstr2=strinf; |
strinf.bufstr=NULL; |
nexttok(); |
} |
} |
RestoreStack(); |
} |
} |
else{ // !=0 |
if((comparetok>=tk_overflowflag)&&(comparetok<=tk_plusflag)){ |
ittok=0x70+comparetok-tk_overflowflag; |
goto endcomp; |
} |
htok2.rm=typenumber(vartype); |
comparetok=tk_notequal; |
ittok2=tk_number; |
htok2.number=0; |
htok2.flag=0; |
} |
if(ittok2==tk_number&&htok2.number==0&&(htok2.flag&f_reloc)==0){ |
if(setzeroflag){ |
if(comparetok==tk_notequal){ |
ittok=0x75; |
goto endcomp; |
} |
if(comparetok==tk_equalto){ |
ittok=0x74; |
goto endcomp; |
} |
} |
if(htok.number==CX&&optimizespeed==0){ |
if(ittok==tk_reg||ittok==tk_reg32){ |
if(comparetok==tk_notequal)use_cxz=notflag==0?cxnzcompr:cxzcompr; |
else if(comparetok==tk_equalto)use_cxz=notflag==TRUE?cxnzcompr:cxzcompr; |
} |
} |
} |
en2: |
if(ittok>=tk_charvar&&ittok<=tk_floatvar){ |
if(ofsstr){ |
int retreg; |
razr=getrazr(vartype); |
if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ |
usereg=retreg==SKIPREG?AX:retreg; |
if(!((ittok2==tk_reg||ittok2==tk_reg32||ittok2==tk_beg)&&usereg==htok2.number)){ |
if(razr==r16)ittok=tk_reg; |
else if(razr==r32)ittok=tk_reg32; |
else ittok=tk_beg; |
htok.number=usereg; |
if(ibuf){ |
free(ibuf); |
ibuf=NULL; |
} |
if(hstr.bufstr){ |
free(hstr.bufstr); |
hstr.bufstr=NULL; |
} |
} |
else{ |
usereg=-1; |
} |
} |
else{ |
if(ittok==tk_floatvar)ClearReg(AX); |
else if(ittok>=tk_intvar&&ittok<tk_floatvar){ |
switch(ittok2){ |
case tk_reg: |
case tk_reg32: |
case tk_number: |
case tk_postnumber: |
case tk_undefofs: |
break; |
default: |
usereg2=0; |
break; |
} |
} |
else{ |
switch(ittok2){ |
case tk_reg: |
case tk_reg32: |
ClearReg(AX); |
case tk_number: |
case tk_beg: |
break; |
default: |
usereg2=0; |
break; |
} |
} |
} |
} |
} |
if(ittok==tk_number&&htok.flag==0&&ittok2==tk_number&&htok2.flag==0){ |
invertflag=(htok.number!=htok2.number?zerocompr:voidcompr); |
useinline=oinline; |
return invertflag; |
} |
if((ittok==tk_number||ittok==tk_postnumber)&&(ittok2==tk_number||ittok2==tk_postnumber))usereg=0; |
#ifdef OPTVARCONST |
if(comconst){ |
if(comparetok==tk_equalto||comparetok==tk_notequal){ |
if(ittok>=tk_charvar&&ittok<=tk_doublevar&&ittok2==tk_number&& |
(htok2.flag&f_reloc)==0&&htok.rec&&(htok.flag&f_useidx)==0){ |
comconst->rec=htok.rec; |
comconst->lnumber=htok2.lnumber; |
comconst->contype=htok2.rm; |
} |
else if(ittok2>=tk_charvar&&ittok2<=tk_doublevar&&ittok==tk_number&& |
(htok.flag&f_reloc)==0&&htok2.rec&&(htok2.flag&f_useidx)==0){ |
comconst->rec=htok2.rec; |
comconst->lnumber=htok.lnumber; |
comconst->contype=htok.rm; |
} |
comconst->typevar=comparetok; |
if(notflag)comconst->typevar=(comparetok==tk_equalto?tk_notequal:tk_equalto); |
} |
} |
#endif |
if(outcmp(0,ittok,&htok,ibuf,&hstr,ittok2,&htok2,ibuf2,&hstr2,razr)){ |
switch(comparetok){ |
case tk_less: comparetok=tk_greater; break; |
case tk_lessequal: comparetok=tk_greaterequal; break; |
case tk_greater: comparetok=tk_less; break; |
case tk_greaterequal: comparetok=tk_lessequal; break; |
} |
} |
createopcode: |
jumptype=0; |
if(vartype==tk_char||vartype==tk_int||vartype==tk_long)jumptype=1; |
switch(comparetok){ |
case tk_equalto: ittok=0x74; break; |
case tk_notequal: ittok=0x75; break; |
case tk_greater: |
ittok=(jumptype==0?0x77:0x7F); |
break; |
case tk_less: |
ittok=(jumptype==0?0x72:0x7C); |
break; |
case tk_greaterequal: |
ittok=(jumptype==0?0x73:0x7D); |
break; |
case tk_lessequal: |
ittok=(jumptype==0?0x76:0x7E); |
break; |
default: unknowncompop(); break; |
} |
endcomp: |
if(ofsstr){ |
if(usereg!=-1)IDZToReg(ofsstr,usereg,razr); |
free(ofsstr); |
} |
if(ofsstr2){ |
// printf("usereg2=%08X %s\n",usereg2,ofsstr2); |
if(usereg2!=-1)IDZToReg(ofsstr2,usereg2,razr); |
free(ofsstr2); |
} |
if(invertflag==2)invertflag=((outptr+2-startloc)>128?1:0); |
ittok^=invertflag; |
ittok^=notflag; |
op(ittok); /* output instruction code */ |
expecting(tk_closebracket); |
useinline=oinline; |
return invertflag|use_cxz; |
} |
|
#ifdef OPTVARCONST |
ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst) |
#else |
ICOMP *compare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg) |
#endif |
{ |
unsigned int i; |
ICOMP *icomp; |
int j=0; |
int ifline=linenumber; |
int ptok=tk_oror; |
int rcompr; |
int useor=FALSE; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
if(am32)j=2; |
icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); //áëîê äëÿ èíôî î ñðàâíåíèÿõ |
i=0; |
|
do{ |
#ifdef OPTVARCONST |
if((rcompr=constructcompare(0,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1; |
#else |
if((rcompr=constructcompare(0,outptr))==voidcompr||rcompr==zerocompr)i=1; |
#endif |
if(i){ |
if(rcompr==voidcompr&&ptok==tk_andand){ |
i=0; |
ptok=tok; |
} |
continue; |
} |
op(0x03+j); |
if(tok!=tk_oror){ |
JXorJMP(); |
if(am32!=FALSE)outword(0); |
outword(0); |
} |
(icomp+*numcomp)->loc=outptr; |
(icomp+*numcomp)->type=tok; |
// (icomp+*numcomp)->use_cxz=rcompr&0xFC; |
(*numcomp)++ ; |
if(*numcomp==MAXIF){ |
ManyLogicCompare(); |
free(icomp); |
return NULL; |
} |
ptok=tok; |
/* if(tok!=tk_andand&&tok!=tk_oror&&bakregstat==NULL){ |
bakregstat=BakRegStat(); |
changeregstat=BakRegStat(); |
}*/ |
}while(tok==tk_oror||tok==tk_andand); |
if(tok==tk_closebracket)nexttok(); |
for(i=0;i<*numcomp;i++){ |
unsigned long temp=outptr-(icomp+i)->loc; |
if((icomp+i)->type==tk_oror){ |
#ifdef OPTVARCONST |
if(comconst)comconst->rec=NULL; |
#endif |
if(temp>127)CompareOr(); |
output[(icomp+i)->loc-1]=(unsigned char)temp; |
clearregstat(); |
useor=TRUE; |
} |
else if(chip>2){ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)temp; |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)temp; |
} |
} |
|
if(bakregstat==NULL){ |
bakregstat=BakRegStat(); |
changeregstat=BakRegStat(); |
} |
if(type==tk_if&&rcompr!=zerocompr){ |
if(rcompr==voidcompr)warcompeqconst(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){ |
if(insertmode||(!optimizespeed)){ |
if(tok==tk_return||tok==tk_RETURN)goto merge_if; |
} |
} |
startblock(); |
doreturn(tok); |
endblock(); |
int di; |
if(rcompr==voidcompr)di=0; |
else di=am32==FALSE?2:4; |
for(unsigned int i=0;i<*numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-di]=(unsigned short)(outptr-(icomp+i)->loc); |
else *(unsigned long *)&output[(icomp+i)->loc-di]=(unsigned long)(outptr-(icomp+i)->loc); |
} |
} |
if((outptr-icomp->loc)<=127)warningjmp(mesIF,ifline); |
if(tok==tk_else||tok==tk_ELSE){ |
notunreach=TRUE; |
nexttok(); |
docommand(); |
} |
free(icomp); |
return NULL; |
} |
if(tok==tk_break||tok==tk_BREAK||tok==tk_continue||tok==tk_CONTINUE||tok==tk_goto||tok==tk_GOTO){ |
merge_if: |
if(rcompr==voidcompr)goto endp; |
if(chip<3){ |
for(i=0;i<*numcomp;i++){ |
if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-3-j); |
else{ |
if((icomp+i)->type!=tk_andand)output[(icomp+i)->loc-5-j]=(unsigned char)(output[(icomp+i)->loc-5-j]^1); |
else{ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); |
} |
} |
} |
outptr-=3+j; |
} |
else{ |
for(i=0;i<*numcomp;i++){ |
if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]=(unsigned char)(output[(icomp+i)->loc-1]-2-j); |
else{ |
if((icomp+i)->type!=tk_andand){ |
output[(icomp+i)->loc-4-j]=(unsigned char)(output[(icomp+i)->loc-3-j]-0x10); |
output[(icomp+i)->loc-3-j]=(unsigned char)(3+j); |
} |
else{ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc+1); |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc+1); |
} |
} |
} |
outptr-=2+j; |
if(cpu<3)cpu=3; |
} |
int delta=0; //new 07.06.06 20:27 |
|
if(tok==tk_break||tok==tk_BREAK){ |
if(useor==FALSE){ |
int ooutptr=outptr-2; |
int otok=tok; |
i=(unsigned char)(output[ooutptr]^1); |
outptr--; |
if(tok==tk_break)i+=0x10; |
else outptr--; |
doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32))); |
if(otok==tk_break){ |
output[ooutptr]=0x0f; |
output[ooutptr+1]=i; |
delta=-1; |
} |
else{ |
output[ooutptr]=i; |
delta=(am32==TRUE?-5:-3); |
} |
} |
else{ |
if(tok==tk_BREAK){ |
output[outptr-1]-=(am32==TRUE?3:1); |
} |
doBREAK((unsigned char)(tok==tk_BREAK?BREAK_SHORT:(am32==FALSE?BREAK_NEAR:BREAK_32))); |
} |
} |
else if(tok==tk_return||tok==tk_RETURN){ |
//new 07.06.06 21:12 |
if(useor==FALSE){ |
int ooutptr=outptr-2; |
int otok=tok; |
i=(unsigned char)(output[ooutptr]^1); |
outptr--; |
if(tok==tk_return){ |
i+=0x10; |
} |
else outptr--; |
AddRetList(outptr+1,linenumber,tok); |
if(tok2==tk_openbracket){ |
nexttok(); |
nexttok(); |
} |
if(otok==tk_return){ |
output[ooutptr]=0x0f; |
output[ooutptr+1]=i; |
delta=-1; |
} |
else{ |
output[ooutptr]=i; |
delta=(am32==TRUE?-5:-3); |
} |
} |
else{ |
if(tok==tk_RETURN)output[outptr-1]-=(am32==TRUE?3:1); |
AddRetList(outptr+1,linenumber,tok); |
if(tok==tk_return&&tok2==tk_openbracket){ |
nexttok(); |
nexttok(); |
} |
} |
nextseminext(); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
} |
else if(tok==tk_goto||tok==tk_GOTO){ |
int ooutptr=outptr; |
if(useor==FALSE){ |
if(tok==tk_GOTO){ |
outptr-=2; |
i=(unsigned char)(output[outptr]^1); |
GOTOdo(); |
output[outptr-2]=i; |
delta=(am32==0?-3:-5); |
} |
else{ |
int otok2=tok2; |
gotodo(); |
if(output[ooutptr]==0xEB){ //áûë êîðîòêèé ïåðåõîä |
outptr=ooutptr-2; |
op(output[outptr]^1); |
op(output[ooutptr+1]+2); |
delta=(am32==0?-3:-5); |
} |
else if(am32&&otok2==tk_number){ |
outptr=ooutptr-2; |
i=(unsigned char)((output[outptr]^1)+0x10); |
op(0x0f); |
op(i); |
if(output[outptr]==0xE9)outdword(*(unsigned long *)&output[ooutptr+1]+1); |
else outdword(*(unsigned short *)&output[ooutptr+2]); |
delta=-1; |
} |
} |
} |
else{ // useor |
if(tok==tk_goto)gotodo(); |
else GOTOdo(); |
if(output[ooutptr]==0xEB){ //áûë êîðîòêèé ïåðåõîä |
output[ooutptr-1]-=(am32==TRUE?3:1); |
} |
} |
} |
else{ |
if(useor==FALSE){ |
int ooutptr=outptr-2; |
int otok=tok; |
i=(unsigned char)(output[ooutptr]^1); |
outptr--; |
if(tok==tk_continue)i+=0x10; |
else outptr--; |
doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32))); |
if(otok==tk_continue){ |
output[ooutptr]=0x0f; |
output[ooutptr+1]=i; |
delta=-1; |
} |
else{ |
output[ooutptr]=i; |
delta=(am32==TRUE?-5:-3); |
} |
} |
else{ |
if(tok==tk_CONTINUE){ |
output[outptr-1]-=(am32==TRUE?3:1); |
} |
doCONTINUE((unsigned char)(tok==tk_CONTINUE?CONTINUE_SHORT:(am32==FALSE?CONTINUE_NEAR:CONTINUE_32))); |
} |
} |
for(i=0;i<*numcomp;i++){ |
// if((icomp+i)->type==tk_oror)output[(icomp+i)->loc-1]+=delta; |
// else |
if((icomp+i)->type==tk_andand){ |
if(am32==FALSE)*(signed short *)&output[(icomp+i)->loc-2]+=delta; |
else *(signed long *)&output[(icomp+i)->loc-4]+=delta; |
} |
} |
if(tok==tk_else||tok==tk_ELSE){ |
notunreach=TRUE; |
nexttok(); |
docommand(); |
} |
free(icomp); |
return NULL; |
} |
} |
endp: |
if(type!=tk_for){ |
startblock(); |
if(rcompr==zerocompr)warcompneqconst(); |
if(tok==tk_openbrace){ |
if(rcompr==zerocompr){ |
cha=cha2; |
inptr=inptr2; |
SkipBlock(); |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
nexttok(); |
} |
else{ |
#ifdef OPTVARCONST |
if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){ |
Const2VarRec(comconst); |
} |
#endif |
doblock(); |
nexttok(); |
} |
} |
else{ |
if(rcompr==zerocompr){ |
do{ |
nexttok(); |
}while(tok!=tk_semicolon&&tok!=tk_eof); |
} |
else{ |
#ifdef OPTVARCONST |
if(comconst&&comconst->rec&&comconst->typevar==tk_equalto){ |
Const2VarRec(comconst); |
} |
#endif |
docommand(); |
} |
} |
endblock(); |
RestoreStack(); |
} |
if(bakreg)*bakreg=bakregstat; |
if(changereg)*changereg=changeregstat; |
return icomp; |
} |
|
void opt_if_else_stop(unsigned int newptr) |
{ |
unsigned int ooutptr,ooutptrdata; |
unsigned char instr; |
dbgact++; |
ooutptr=outptr; |
ooutptrdata=outptrdata; |
outptr=newptr; |
instr=output[outptr]; |
docommand(); |
if(output[newptr]==0xEB){ |
signed char ofs=output[newptr+1]; |
if(output[newptr-1]==0x0F&&instr>=0x80&&instr<0x90){ |
ofs--; |
if(am32)ofs-=(signed char)2; |
} |
if(am32)*(long *)&output[newptr+1]=ofs; |
else*(short *)&output[newptr+1]=ofs; |
} |
if(am32&&output[newptr]==0x66&&output[newptr+1]==0xE9){ |
signed short ofs=(signed short)(*(short *)&output[newptr+2]-1); |
*(long *)&output[newptr+1]=ofs; |
} |
output[newptr]=instr; |
outptr=ooutptr; |
outptrdata=ooutptrdata; |
dbgact--; |
} |
|
void doif() |
{ |
unsigned int startloc,elseline,numcomp=0,ifline; |
ICOMP *icomp; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
unsigned int oaddESP=addESP; |
ifline=linenumber; |
#ifdef OPTVARCONST |
LVIC comconst; |
comconst.rec=NULL; |
icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat,&comconst); |
#else |
icomp=compare(tk_if,&numcomp,&bakregstat,&changeregstat); |
#endif |
// i=CheckStopBlock(); |
/*-----------------19.08.99 22:35------------------- |
Óáèðàòü else ìîæíî òîëüêî ïîñëå ïåðâîãî if |
Ïîñëå else if â ñëåäóþùèé else óáèðàòü íåëüçÿ |
--------------------------------------------------*/ |
if(icomp!=NULL){ |
elseline=linenumber; |
unsigned long temp; |
unsigned int j=0; |
unsigned int otok=tok; |
unsigned int oinptr=inptr2; |
unsigned char ocha=cha2; |
unsigned int oline=linenumber; |
if(tok==tk_else||tok==tk_ELSE){ |
if(dbg)AddLine(); |
j=(am32==FALSE?3:5); |
if(tok2==tk_goto||tok2==tk_break||tok2==tk_continue||//ïîãëîòèòü èõ |
tok2==tk_RETURN||tok2==tk_return||tok2==tk_GOTO||tok2==tk_BREAK||tok2==tk_CONTINUE){ |
nexttok(); |
switch(tok){ |
case tk_GOTO: otok=tk_goto; break; |
case tk_BREAK: otok=tk_break; break; |
case tk_CONTINUE: otok=tk_continue; break; |
case tk_return: |
case tk_RETURN: |
if(tok2==tk_semicolon||(tok2==tk_openbracket&& |
ScanTok3()==tk_closebracket)){ |
startblock(); |
otok=tk_return; |
break; |
} |
tok=otok; //íåâîçìîæíî îïòèìèçèðîâàòü |
inptr2=oinptr; |
cha2=ocha; |
linenumber=oline; |
goto nooptim; |
default:otok=tok; break; |
} |
oinptr=inptr2; |
ocha=cha2; |
oline=linenumber; |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
notunreach=TRUE; |
tok=otok; |
inptr2=oinptr; |
cha2=ocha; |
linenumber=oline; |
opt_if_else_stop((icomp+i)->loc-j); |
} |
} |
if(otok==tk_return)endblock(); |
if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline); |
free(icomp); |
retproc=FALSE; |
lastcommand=tk_if; |
return; |
} |
nooptim: |
if(tok==tk_ELSE)j=2; |
} |
notunreach=TRUE; |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr+j-(icomp+i)->loc); |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr+j-(icomp+i)->loc); |
} |
} |
if((outptr+j-icomp->loc)<=127)warningjmp(mesIF,ifline); |
switch(lastcommand){ |
case tk_return: |
case tk_RETURN: |
case tk_goto: |
case tk_GOTO: |
case tk_break: |
case tk_BREAK: |
case tk_continue: |
case tk_CONTINUE: |
addESP=oaddESP; |
break; |
} |
if(retproc)CopyRegStat(bakregstat); |
else{ |
switch(lastcommand){ |
case tk_return: |
case tk_RETURN: |
case tk_goto: |
case tk_GOTO: |
case tk_break: |
case tk_BREAK: |
case tk_continue: |
case tk_CONTINUE: |
CopyRegStat(bakregstat); |
break; |
default: |
CompareRegStat(changeregstat); |
break; |
} |
} |
// printf("lastcommand=%d\n",lastcommand); |
// CompareRegStat(changeregstat); |
if(tok==tk_else/*&&i==FALSE*/){ |
addESP=oaddESP; |
RestoreStack(); |
CopyRegStat(bakregstat); |
jumploc0(); |
startloc=outptr; |
getoperand(); |
#ifdef OPTVARCONST |
if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){ |
Const2VarRec(&comconst); |
} |
#endif |
startblock(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(dbg)AddLine(); |
doreturn(tok); |
} |
else docommand(); |
endblock(); |
RestoreStack(); |
temp=outptr-startloc; |
if(temp<=127)warningjmp(mesELSE,elseline); |
if(am32==FALSE)*(unsigned short *)&output[startloc-2]=(unsigned short)temp; |
else *(unsigned long *)&output[startloc-4]=temp; |
CompareRegStat(changeregstat); |
} |
else if(tok==tk_ELSE/*&&i==FALSE*/){ |
addESP=oaddESP; |
RestoreStack(); |
CopyRegStat(bakregstat); |
outword(0x00EB); |
startloc=outptr; |
getoperand(); |
#ifdef OPTVARCONST |
if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal){ |
Const2VarRec(&comconst); |
} |
#endif |
startblock(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(dbg)AddLine(); |
doreturn(tok); |
} |
else docommand(); |
endblock(); |
RestoreStack(); |
temp=outptr-startloc; |
if(temp>127)jumperror(elseline,mesELSE); |
output[startloc-1]=(unsigned char)temp; |
CompareRegStat(changeregstat); |
} |
/* else{ |
if(i!=FALSE&&(tok==tk_else||tok==tk_ELSE))nexttok(); |
}*/ |
free(icomp); |
CopyRegStat(changeregstat); |
} |
FreeStat(bakregstat); |
FreeStat(changeregstat); |
retproc=FALSE; |
lastcommand=tk_if; |
} |
|
#ifdef OPTVARCONST |
ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg,LVIC *comconst) |
#else |
ICOMP *bigcompare(int type,unsigned int *numcomp,REGISTERSTAT **bakreg,REGISTERSTAT **changereg) |
#endif |
{ |
unsigned int ifline; |
ICOMP *icomp; |
unsigned int i=0; |
int j=0; |
int ptok=tk_oror; |
int rcompr; |
int useor=FALSE; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
if(am32!=FALSE)j=2; |
icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); //áëîê äëÿ èíôî î ñðàâíåíèÿõ |
ifline=linenumber; |
do{ |
#ifdef OPTVARCONST |
if((rcompr=constructcompare(1,outptr,comconst))==voidcompr||rcompr==zerocompr)i=1; |
#else |
if((rcompr=constructcompare(1,outptr))==voidcompr||rcompr==zerocompr)i=1; |
#endif |
(icomp+*numcomp)->use_cxz=rcompr&0xFC; |
if(i){ |
if(rcompr==voidcompr&&ptok==tk_andand){ |
i=0; |
ptok=tok; |
} |
continue; |
} |
op(0x00); |
(icomp+*numcomp)->loc=outptr; |
(icomp+*numcomp)->type=tok; |
(*numcomp)++; |
if(*numcomp==MAXIF){ |
ManyLogicCompare(); |
free(icomp); |
return NULL; |
} |
ptok=tok; |
/* if(tok==tk_andand&&bakregstat==NULL){ |
bakregstat=BakRegStat(); |
changeregstat=BakRegStat(); |
}*/ |
}while(tok==tk_oror||tok==tk_andand); |
if(tok==tk_closebracket)nexttok(); |
for(i=0;i<*numcomp;i++){ |
if(outptr-(icomp+i)->loc>127)CompareOr(); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
if((icomp+i)->type==tk_oror){ |
#ifdef OPTVARCONST |
if(comconst)comconst->rec=NULL; |
#endif |
output[(icomp+i)->loc-2]=(unsigned char)(output[(icomp+i)->loc-2]^1); |
clearregstat(); |
useor=TRUE; |
} |
} |
if(bakregstat==NULL){ |
bakregstat=BakRegStat(); |
changeregstat=BakRegStat(); |
} |
if(type==tk_IF&&rcompr!=zerocompr){ |
if(rcompr==voidcompr)warcompeqconst(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(tok2==tk_semicolon||(tok2==tk_openbracket&&ScanTok3()==tk_closebracket)){ |
if(insertmode||(!optimizespeed)){ |
if(tok==tk_RETURN)goto merge_if; |
else if(chip>2&&(insertmode||(paramsize&& |
(current_proc_type&f_typeproc)!=tp_cdecl)))goto merge_if2; |
} |
} |
startblock(); |
doreturn(tok); |
endblock(); |
for(unsigned int i=0;i<*numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
} |
if(tok==tk_else||tok==tk_ELSE){ |
notunreach=TRUE; |
getoperand(); |
docommand(); |
} |
free(icomp); |
return NULL; |
} |
if(tok==tk_BREAK||tok==tk_CONTINUE||tok==tk_GOTO){ |
merge_if: |
int otok=tok; |
for(i=0;i<*numcomp;i++){ |
unsigned char oldcode; |
if(((icomp+i)->type==tk_oror)||((i+1)==*numcomp)){ |
outptr=(icomp+i)->loc-2; |
oldcode=output[outptr]; |
if(tok==tk_BREAK)MakeBreak(BREAK_SHORT); |
else if(tok==tk_RETURN){ |
AddRetList(outptr+1,ifline,tk_RETURN); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
} |
else if(tok==tk_GOTO){ |
if((i+1)!=*numcomp){ |
int optr,ocha,oline; |
optr=inptr2; |
ocha=cha2; |
oline=linenum2; |
GOTOdo(); |
if(outptr!=(icomp+i)->loc)jumperror(oline,"GOTO"); |
inptr2=optr; |
cha2=(unsigned char)ocha; |
linenum2=oline; |
tok=tk_GOTO; |
} |
else{ |
getoperand(); |
CheckIP(); |
if(tok==tk_number||tok==tk_interruptproc||tok==tk_proc){ |
long hnumber; |
if(tok==tk_number)hnumber=doconstdwordmath(); |
else{ |
hnumber=itok.number; |
nexttok(); |
} |
long loc=hnumber-outptr-2; |
if(loc>-129&&loc<128){ |
op((unsigned char)(oldcode^1)); |
op(loc); |
} |
else{ |
loc-=3; |
outptr++; |
op(am32==0?3:5); |
op(0xE9); |
if(am32==FALSE)outword(loc); |
else{ |
loc-=2; |
outdword(loc); |
} |
} |
seminext(); |
break; |
} |
else if(GOTO())nexttok(); |
seminext(); |
} |
} |
else MakeContinue(CONTINUE_SHORT); |
if((i+1)==*numcomp)oldcode^=1; |
output[outptr-2]=oldcode; |
} |
} |
if(tok==tk_RETURN&&tok2==tk_openbracket){ |
nexttok(); |
nexttok(); |
} |
if(otok!=tk_GOTO&&rcompr!=voidcompr)nextseminext(); |
|
if(tok==tk_else||tok==tk_ELSE){ |
notunreach=TRUE; |
getoperand(); |
docommand(); |
} |
free(icomp); |
return NULL; |
} |
if((tok==tk_break||tok==tk_continue||tok==tk_goto)&&chip>2){ |
merge_if2: |
|
// printf("%s (%u) %s %s tok=%d\n",(startfileinfo+currentfileinfo)->filename,linenumber,itok.name,string,tok); |
|
if(*numcomp==1&&(!(tok==tk_goto&&(tok2==tk_reg||tok2==tk_reg32)))){ |
outptr-=2; |
i=(output[outptr]^1)+0x10; |
op(0x0F); |
} |
if(tok==tk_break)doBREAK((unsigned char)(am32==FALSE?BREAK_NEAR:BREAK_32)); |
else if(tok==tk_return){ |
AddRetList(outptr+1,ifline,tk_return); |
if(tok2==tk_openbracket){ |
nexttok(); |
nexttok(); |
} |
nextseminext(); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
} |
else if(tok==tk_goto){ |
nexttok(); |
CheckIP(); |
if((tok==tk_number&&*numcomp==1)||tok==tk_interruptproc||tok==tk_proc){ |
if(tok==tk_proc&&tok2==tk_openbracket)doanyproc(TRUE); |
else{ |
long hnumber; |
if(tok==tk_number)hnumber=doconstdwordmath(); |
else{ |
hnumber=itok.number; |
nexttok(); |
} |
long loc=hnumber-outptr-2; |
if(loc>-130&&loc<127){ |
outptr--; |
op((unsigned char)(i-0x10)); |
op(loc+1); |
seminext(); |
goto c1; |
} |
else{ |
loc--; |
op(0xE9); |
if(am32==FALSE)outword(loc); |
else{ |
loc-=2; |
outdword(loc); |
} |
} |
} |
} |
else{ |
if(tok==tk_reg||tok==tk_reg32){ |
i=outptr; |
if(gotol(0))nexttok(); |
i=outptr-i; |
output[outptr-i-1]=(unsigned char)i; |
goto c1; |
} |
if(gotol(0))nexttok(); |
} |
seminext(); |
} |
else doCONTINUE((unsigned char)(am32==FALSE?CONTINUE_NEAR:CONTINUE_32)); |
if(*numcomp==1)output[outptr-3-j]=(unsigned char)i; |
c1: |
if(cpu<3)cpu=3; |
if(tok==tk_else||tok==tk_ELSE){ |
notunreach=TRUE; |
getoperand(); |
docommand(); |
} |
if(*numcomp!=1){ |
for(unsigned int i=0;i<*numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesIF); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
} |
} |
free(icomp); |
return NULL; |
} |
} |
if((icomp+(*numcomp-1))->use_cxz==cxnzcompr){ |
outptr-=4; |
outword(0xE3); |
(icomp+(*numcomp-1))->loc=outptr; |
for(i=(*numcomp-1);i!=0;i--){ |
if((icomp+i-1)->type==tk_oror)output[(icomp+i-1)->loc-1]-=(unsigned char)2; |
} |
} |
if(type!=tk_FOR){ |
startblock(); |
if(rcompr==zerocompr)warcompneqconst(); |
if(tok==tk_openbrace){ |
if(rcompr==zerocompr){ |
cha=cha2; |
inptr=inptr2; |
SkipBlock(); |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
nexttok(); |
} |
else{ |
#ifdef OPTVARCONST |
if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst); |
#endif |
doblock(); |
nexttok(); |
} |
} |
else{ |
if(rcompr==zerocompr){ |
do{ |
nexttok(); |
}while(tok!=tk_semicolon&&tok!=tk_eof); |
} |
else{ |
#ifdef OPTVARCONST |
if(comconst&&comconst->rec&&comconst->typevar==tk_equalto)Const2VarRec(comconst); |
#endif |
docommand(); |
} |
} |
endblock(); |
RestoreStack(); |
} |
if(bakreg)*bakreg=bakregstat; |
if(changereg)*changereg=changeregstat; |
return icomp; |
} |
|
void dobigif() |
{ |
unsigned int ifline,numcomp=0,j=0; |
ICOMP *icomp; |
int ic; |
unsigned int oaddESP=addESP; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
ifline=linenumber; |
#ifdef OPTVARCONST |
LVIC comconst; |
comconst.rec=NULL; |
icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat,&comconst); |
#else |
icomp=bigcompare(tk_IF,&numcomp,&bakregstat,&changeregstat); |
#endif |
if(icomp!=NULL){ |
unsigned int elseline; |
elseline=linenumber; |
if(tok==tk_else)j=(am32==FALSE?3:5); |
else if(tok==tk_ELSE)j=2; |
notunreach=TRUE; |
if(dbg)AddLine(); |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if((outptr+j-(icomp+i)->loc)>127)jumperror(ifline,mesIF); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr+j-(icomp+i)->loc); |
} |
} |
switch(lastcommand){ |
case tk_return: |
case tk_RETURN: |
case tk_goto: |
case tk_GOTO: |
case tk_break: |
case tk_BREAK: |
case tk_continue: |
case tk_CONTINUE: |
addESP=oaddESP; |
break; |
} |
if(retproc)CopyRegStat(bakregstat); |
else{ |
switch(lastcommand){ |
case tk_return: |
case tk_RETURN: |
case tk_goto: |
case tk_GOTO: |
case tk_break: |
case tk_BREAK: |
case tk_continue: |
case tk_CONTINUE: |
CopyRegStat(bakregstat); |
break; |
default: |
CompareRegStat(changeregstat); |
break; |
} |
// CompareRegStat(changeregstat); |
} |
if(tok==tk_else/*&&i==FALSE*/){ |
addESP=oaddESP; |
RestoreStack(); |
CopyRegStat(bakregstat); |
jumploc0(); |
ic = outptr; |
getoperand(); |
#ifdef OPTVARCONST |
if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst); |
#endif |
startblock(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(dbg)AddLine(); |
doreturn(tok); |
} |
else docommand(); |
endblock(); |
RestoreStack(); |
if((outptr-ic)<=127)warningjmp(mesELSE,elseline); |
if(am32==FALSE)*(unsigned short *)&output[ic-2]=(unsigned short)(outptr-ic); |
else *(unsigned long *)&output[ic-4]=(unsigned long)(outptr-ic); |
CompareRegStat(changeregstat); |
} |
else if(tok==tk_ELSE/*&&ic==FALSE*/){ |
addESP=oaddESP; |
RestoreStack(); |
CopyRegStat(bakregstat); |
outword(0x00EB); |
ic=outptr; |
getoperand(); |
#ifdef OPTVARCONST |
if(tok!=tk_if&&tok!=tk_IF&&comconst.rec&&comconst.typevar==tk_notequal)Const2VarRec(&comconst); |
#endif |
startblock(); |
if(tok==tk_return||tok==tk_RETURN){ |
if(dbg)AddLine(); |
doreturn(tok); |
} |
else docommand(); |
endblock(); |
RestoreStack(); |
if((outptr-ic)>127)jumperror(elseline,mesELSE); |
output[ic-1]=(unsigned char)(outptr-ic); |
CompareRegStat(changeregstat); |
} |
free(icomp); |
CopyRegStat(changeregstat); |
} |
FreeStat(bakregstat); |
FreeStat(changeregstat); |
retproc=FALSE; |
lastcommand=tk_IF; |
} |
|
void JXorJMP() |
{ |
if(chip<3){ |
op(0xE9); |
} |
else{ |
unsigned char i; |
outptr-=2; |
i=(unsigned char)((output[outptr]^1)+0x10); |
op(0x0F); op(i); |
if(cpu<3)cpu=3; |
} |
} |
|
void dowhile(unsigned int typeb) |
{ |
unsigned int ifline,conloc,numcomp=0; |
ICOMP *icomp; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
uptdbr(); |
if(AlignCycle)AlignCD(CS,aligncycle); |
conloc=outptr; |
ifline=linenumber; |
if(typeb==tk_while) |
#ifdef OPTVARCONST |
icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); |
#else |
icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat); |
#endif |
else |
#ifdef OPTVARCONST |
icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); |
#else |
icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat); |
#endif |
SetContinueLabel(); |
jumploc(conloc); |
if(icomp!=NULL){ |
if(typeb==tk_WHILE){ |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesWHILE); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
} |
} |
else{ |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); |
} |
} |
if((outptr-icomp->loc)<=127)warningjmp(mesWHILE,ifline); |
} |
free(icomp); |
} |
if(retproc){ |
if(bakregstat)CopyRegStat(bakregstat); |
} |
else if(changeregstat)CompareRegStat(changeregstat); |
if(changeregstat)CopyRegStat(changeregstat); |
SetBreakLabel(); |
if(usebr[curbr]!=0)clearregstat(); |
FreeStat(bakregstat); |
FreeStat(changeregstat); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
lastcommand=tk_do; |
} |
|
void dowhilefast(unsigned int typeb) |
{ |
unsigned int numcomp=0; |
unsigned int startloc,i; |
ICOMP *icomp; |
ITOK oitok,ostructadr; |
SINFO ostr; |
unsigned int oldinptr; |
int otok,otok2; |
char *ostring,*obufrm; |
int blinenum,olinenum,oinptr; |
char *ostartline,*bstartline; |
char ocha,bcha; |
int jmptocompr=0; |
int rcompr; |
unsigned char *oinput; |
unsigned int oaddESP=addESP; |
ocha=cha2; |
oinptr=inptr2; |
olinenum=linenumber; |
ostartline=startline; |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
do{ |
nexttok(); |
if(tok2==tk_openbracket)nexttok(); |
if(tok2==tk_closebracket){ |
nexttok(); |
jmptocompr=1; |
break; |
} |
if(tok2==tk_number){ |
nexttok(); |
if(tok2==tk_closebracket){ |
if(itok.number!=0)jmptocompr=1; |
else jmptocompr=2; |
nexttok(); |
break; |
} |
} |
nexttok(); //íåîáõîäèìî äëÿ èçáåæàíèÿ ïðåäóïðåæäåíèÿ î íåèíèöèàëèçèðîâàííîé ïåðåìåííîé |
cha=cha2; |
inptr=inptr2; |
SkipParam(); |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
nexttok(); |
if(typeb==tk_while&&tok==tk_oror&&optimizespeed==0){ |
cha2=ocha; |
inptr2=oinptr; |
linenumber=linenum2=olinenum; |
startline=ostartline; |
dowhile(typeb); |
if(ESPloc&&am32&&oaddESP!=addESP)warESP(); |
return; |
} |
if(bufrm){ |
free(bufrm); |
bufrm=NULL; |
} |
if(strinf.bufstr){ |
free(strinf.bufstr); |
strinf.bufstr=NULL; |
} |
}while(tok==tk_andand||tok==tk_oror); |
while(tok==tk_closebracket)nexttok(); |
if(!jmptocompr){ |
if(typeb==tk_WHILE)outword(0x00EB); // JMP SHORT |
else jumploc0(); |
} |
i=outptr; |
if(AlignCycle)AlignCD(CS,aligncycle); |
startloc=outptr; |
uptdbr(); |
if(tok!=tk_openbrace){ |
if(jmptocompr==2){ |
do{ |
nexttok(); |
}while(tok!=tk_semicolon&&tok!=tk_eof); |
} |
else docommand(); |
} |
else{ |
if(jmptocompr==2){ |
cha=cha2; |
inptr=inptr2; |
SkipBlock(); |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
nexttok(); |
} |
else{ |
startblock(); |
doblock(); |
nexttok(); |
endblock(); |
} |
} |
RestoreStack(); |
if(!jmptocompr){ |
if(typeb==tk_WHILE){ |
if(i!=outptr){ |
if((outptr-i)>127)jumperror(olinenum,mesWHILE); |
output[i-1]=(unsigned char)(outptr-i); |
} |
else{ |
if(dbg&1)KillLastLine(); |
outptr-=2; |
startloc-=2; |
} |
} |
else{ |
if(i!=outptr){ |
if((outptr-i)<=127)warningjmp(mesWHILE,olinenum); |
if(am32) *(unsigned long *)&output[i-4]=(unsigned long)(outptr-i); |
else *(unsigned short *)&output[i-2]=(unsigned short)(outptr-i); |
} |
else{ |
i=3; |
if(am32)i+=2; |
if(dbg){ |
KillLastLine(); |
KillLastLine(); |
} |
outptr-=i; |
startloc-=i; |
} |
} |
} |
SetContinueLabel(); |
clearregstat(); //06.09.04 21:56 |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); //áëîê äëÿ èíôî î ñðàâíåíèÿõ |
// oitok2=itok2; |
|
ostring=BackString((char *)string); |
oldinptr=inptr2; |
oinput=input; |
bcha=cha2; |
otok=tok; |
otok2=tok2; |
oitok=itok; |
ostructadr=structadr; |
ostr=strinf; |
strinf.bufstr=NULL; |
obufrm=bufrm; |
int oldendinptr=endinptr; |
COM_MOD *tempcurmod=cur_mod; |
if(cur_mod)BackMod(); |
|
bufrm=NULL; |
blinenum=linenum2; |
inptr2=oinptr; |
cha2=ocha; |
linenumber=linenum2=olinenum; |
bstartline=startline; |
startline=ostartline; |
|
if(dbg)AddLine(); |
int ptok=tk_oror; |
do{ |
i=0; |
#ifdef OPTVARCONST |
if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1; |
#else |
if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1; |
#endif |
if(i){ |
if(ptok==tk_andand){ |
// i=0; |
ptok=tok; |
} |
continue; |
} |
if((rcompr&1)){; |
op(0x03); |
if(tok!=tk_andand){ |
JXorJMP(); |
if(am32==FALSE)outword(startloc-(outptr+2)); |
else outdword(startloc-(outptr+4)); |
} |
} |
else{ |
op(startloc-(outptr+1)); /* the small jump */ |
if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1); |
} |
(icomp+numcomp)->loc=outptr; |
(icomp+numcomp)->type=tok; |
numcomp++; |
if(numcomp==MAXIF){ |
ManyLogicCompare(); |
break; |
} |
ptok=tok; |
}while(tok==tk_oror||tok==tk_andand); |
if(jmptocompr==1)jumploc(startloc); |
|
startline=bstartline; |
strinf=ostr; |
inptr2=oldinptr; |
input=oinput; |
endinptr=oldendinptr; |
cha2=bcha; |
tok=otok; |
itok=oitok; |
structadr=ostructadr; |
bufrm=obufrm; |
tok2=otok2; |
cur_mod=tempcurmod; |
strcpy((char *)string,ostring); |
free(ostring); |
linenumber=linenum2=blinenum; |
itok2=oitok; |
|
for(i=0;i<numcomp;i++){ |
if((icomp+i)->type==tk_andand){ |
if(outptr-(icomp+i)->loc>127)CompareOr(); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
} |
if(rcompr==cxzcompr){ |
outptr-=4; |
op(0xE3); |
op(startloc-outptr-1); |
for(i=(numcomp-1);i!=0;i--){ |
if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2; |
} |
} |
SetBreakLabel(); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
free(icomp); |
if(ESPloc&&am32&&oaddESP!=addESP)warESP(); |
lastcommand=tk_do; |
} |
|
void dodo() |
{ |
unsigned int startloc,numcomp=0,i=0; |
ICOMP *icomp; |
int ptok=tk_oror; |
int rcompr; |
unsigned int oaddESP=addESP; |
nexttok(); |
if(AlignCycle)AlignCD(CS,aligncycle); |
startloc=outptr; |
uptdbr(); |
if(dbg&1)KillLastLine(); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
docommand(); |
SetContinueLabel(); |
if(dbg)AddLine(); |
if(tok!=tk_while)preerror("'while' expected following 'do'"); |
icomp=(ICOMP *)MALLOC(sizeof(ICOMP)*MAXIF); //áëîê äëÿ èíôî î ñðàâíåíèÿõ |
do{ |
#ifdef OPTVARCONST |
if((rcompr=constructcompare(2,startloc,NULL))==voidcompr||rcompr==zerocompr)i=1; |
#else |
if((rcompr=constructcompare(2,startloc))==voidcompr||rcompr==zerocompr)i=1; |
#endif |
if(i){ |
if(ptok==tk_andand){ |
i=0; |
ptok=tok; |
} |
continue; |
} |
if((rcompr&1)){; |
op(0x03); |
if(tok!=tk_andand){ |
JXorJMP(); |
if(am32==FALSE)outword(startloc-(outptr+2)); |
else outdword(startloc-(outptr+4)); |
} |
} |
else{ |
op(startloc-(outptr+1)); /* the small jump */ |
if(tok==tk_andand)output[outptr-2]=(unsigned char)(output[outptr-2]^1); |
} |
(icomp+numcomp)->loc=outptr; |
(icomp+numcomp)->type=tok; |
numcomp++; |
if(numcomp==MAXIF){ |
ManyLogicCompare(); |
goto end; |
} |
ptok=tok; |
}while(tok==tk_oror||tok==tk_andand); |
if(i)jumploc(startloc); |
if(tok==tk_closebracket)nexttok(); |
for(i=0;i<numcomp;i++){ |
if((icomp+i)->type==tk_andand){ |
if(outptr-(icomp+i)->loc>127)CompareOr(); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
} |
if(rcompr==cxzcompr){ |
outptr-=4; |
op(0xE3); |
op(startloc-outptr-1); |
for(i=(numcomp-1);i!=0;i--){ |
if((icomp+i-1)->type==tk_andand)output[(icomp+i-1)->loc-1]-=(unsigned char)2; |
} |
} |
seminext(); |
SetBreakLabel(); |
if(usebr[curbr]!=0||useco[curco]!=0)clearregstat(); |
end: |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
free(icomp); |
if(ESPloc&&am32&&oaddESP!=addESP)warESP(); |
lastcommand=tk_do; |
} |
|
void dofor(unsigned int typeb) |
{ |
unsigned int ifline,conloc,blinenum,numcomp=0; |
unsigned char bcha; |
unsigned char COMPARE=FALSE,modif=FALSE; |
int i; |
unsigned char *buf; |
unsigned int oaddESP=addESP; |
ICOMP *icomp=NULL; |
REGISTERSTAT *bakregstat=NULL,*changeregstat=NULL; |
ifline=linenumber; |
// printf("start for, curco=%u curbr=%u\n",curco,curbr); |
uptdbr(); |
nexttok(); |
i=inptr2; |
bcha=cha2; |
expecting(tk_openbracket); //ïðîâ íà îòêð ñêîáêó |
if(tok!=tk_semicolon){ //ÅÑÒÜ ÏÐÅÄÂÀÐÈÒÅËÜÍÛÅ ÓÑÒÀÍÎÂÊÈ |
for(;;){ //çàïèñàòü èõ â áóôåð |
AddBackBuf(i,bcha); |
if(tok==tk_semicolon)break; |
if(tok!=tk_camma){ |
expecting(tk_semicolon); |
break; |
} |
i=inptr2; |
bcha=cha2; |
nexttok(); |
} |
if(bufrm){ |
free(bufrm); |
bufrm=NULL; |
} |
if(strinf.bufstr){ |
free(strinf.bufstr); |
strinf.bufstr=NULL; |
} |
CharToBackBuf('}'); |
CharToBackBuf(0); |
RunBackText(); //âûïîëíèòü åãî |
} |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
bcha=cha2; |
i=inptr2; |
nexttok(); |
if(AlignCycle)AlignCD(CS,aligncycle); |
conloc=outptr; //çàïîìíèòü òî÷êó íà÷àëà öèêëà |
|
if(tok!=tk_semicolon){ //åñëè åñòü óñëîâèå |
if(tok!=tk_openbracket){ //åñëè óñëîâèå íà÷èíàåòñÿ íå ñ ( |
CharToBackBuf('('); //äîáàâèòü åå |
COMPARE=TRUE; //è ôëàã óñòàíîâèòü |
} |
AddBackBuf(i,bcha); //çàïîìíèòü óñëîâèå |
if(tok!=tk_semicolon)expected(';'); |
SizeBackBuf--; |
if(COMPARE)CharToBackBuf(')'); //åñëè íàäî, çàêðûòü ñêîáêó |
CharToBackBuf(0); |
int oendinptr=endinptr; |
endinptr=SizeBackBuf-1;//strlen(BackTextBlock); |
i=inptr2; |
buf=input; |
bcha=cha2; |
input=(unsigned char *)BackTextBlock; |
SizeBackBuf=0; |
inptr2=1; |
cha2='('; |
if(typeb==tk_for) |
#ifdef OPTVARCONST |
icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); |
#else |
icomp=compare(typeb,&numcomp,&bakregstat,&changeregstat); |
#endif |
else |
#ifdef OPTVARCONST |
icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat,NULL); |
#else |
icomp=bigcompare(typeb,&numcomp,&bakregstat,&changeregstat); |
#endif |
free(input); |
input=buf; |
inptr2=i; |
cha2=bcha; |
endinptr=oendinptr; |
COMPARE=TRUE; |
nexttok(); |
} |
else{ |
i=inptr2; |
bcha=cha2; |
nexttok(); |
} |
|
if(tok!=tk_closebracket){ //åñòü ìîäèôèêàöèÿ |
modif=TRUE; |
while(tok!=tk_closebracket){ |
AddBackBuf(i,bcha); |
if(cha==')'||cha==26){ |
CharToBackBuf(';'); |
nextchar(); |
cha2=cha; |
inptr2=inptr; |
break; |
} |
if(bufrm){ |
free(bufrm); |
bufrm=NULL; |
} |
if(strinf.bufstr){ |
free(strinf.bufstr); |
strinf.bufstr=NULL; |
} |
i=inptr2; |
bcha=cha2; |
nexttok(); |
} |
CharToBackBuf('}'); |
CharToBackBuf(0); |
buf=(unsigned char *)REALLOC(BackTextBlock,SizeBackBuf); |
SizeBackBuf=0; |
} |
|
blinenum=linenumber; |
nexttok(); |
/////////////////// |
if(tok==tk_openbrace){ |
if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){ |
warcompneqconst(); |
cha=cha2; |
inptr=inptr2; |
SkipBlock(); |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
nexttok(); |
} |
else{ |
startblock(); |
doblock(); |
nexttok(); |
endblock(); |
} |
} |
else{ |
if(COMPARE&&(icomp+numcomp)->use_cxz==zerocompr){ |
warcompneqconst(); |
do{ |
nexttok(); |
}while(tok!=tk_semicolon&&tok!=tk_eof); |
} |
else docommand(); |
} |
|
RestoreStack(); |
SetContinueLabel(); |
// puts((char *)string2); |
// printf("end for, curco=%u curbr=%u\n",curco,curbr); |
if(modif){ |
unsigned int oldlinenum=linenum2; |
ITOK oitok; |
oitok=itok2; |
BackTextBlock=(char *)buf; |
linenum2=blinenum; |
RunBackText(); |
linenumber=linenum2=oldlinenum; |
itok2=oitok; |
} |
|
if(COMPARE==FALSE||(COMPARE&&(icomp+numcomp)->use_cxz!=zerocompr)){ |
if(COMPARE&&(icomp+numcomp)->use_cxz==voidcompr)warcompeqconst(); |
jumploc(conloc);//JMP íà íà÷àëî öèêëà |
} |
|
if(COMPARE){ |
for(unsigned int i=0;i<numcomp;i++){ |
if((icomp+i)->type!=tk_oror){ |
if(typeb==tk_FOR){ |
if((outptr-(icomp+i)->loc)>127)jumperror(ifline,mesFOR); |
output[(icomp+i)->loc-1]=(unsigned char)(outptr-(icomp+i)->loc); |
} |
else{ |
if((outptr-(icomp+i)->loc)<=127)warningjmp(mesFOR,ifline); |
if(am32==FALSE)*(unsigned short *)&output[(icomp+i)->loc-2]=(unsigned short)(outptr-(icomp+i)->loc); |
else *(unsigned long *)&output[(icomp+i)->loc-4]=(unsigned long)(outptr-(icomp+i)->loc); |
} |
} |
} |
free(icomp); |
} |
if(retproc){ |
if(bakregstat)CopyRegStat(bakregstat); |
} |
else if(changeregstat)CompareRegStat(changeregstat); |
if(changeregstat)CopyRegStat(changeregstat); |
SetBreakLabel(); |
if(usebr[curbr]!=0||useco[curco]!=0)clearregstat(); |
FreeStat(bakregstat); |
FreeStat(changeregstat); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
if(ESPloc&&am32&&oaddESP!=addESP)warESP(); |
lastcommand=tk_for; |
} |
|
void decit(int dectok,ITOK *detok,char *&decbuf,SINFO *dstr) |
// outputs code to decrement the given variable one. |
{ |
int vop=0,i=0,razr=r16; |
switch(dectok){ |
case tk_dwordvar: |
case tk_longvar: |
CheckAllMassiv(decbuf,4,dstr,detok); |
op66(r32); |
if(cpu<3)cpu=3; |
vop=1; |
goto l2; |
case tk_wordvar: |
case tk_intvar: vop=1; |
op66(r16); |
i=1; |
case tk_bytevar: |
case tk_charvar: |
i++; |
CheckAllMassiv(decbuf,i,dstr,detok); |
if(vop!=0)op66(r16); |
l2: |
outseg(detok,2); |
op(0xFE + vop); |
op(0x08+detok->rm); |
outaddress(detok); |
break; |
case tk_reg32: |
if(cpu<3)cpu=3; |
razr=r32; |
case tk_reg: |
op66(razr); |
op(0x48+detok->number); |
break; |
case tk_beg: |
op(0xFE); |
op(0xC8+detok->number); |
break; |
default: |
preerror(invaliddecrem); |
break; |
} |
} |
|
void uptdbr(/*int usesw*/) |
{ |
listbr[curbr]=numbr; //íîìåð ýòîãî öèêëà |
usebr[curbr]=0; |
curbr++; //÷èñëî âëîæåíèé |
numbr++; //âñåãî öèêëîâ |
// if(!usesw){ |
useco[curco]=0; |
curco++; |
// } |
if(curbr==MAXIN)preerror("to many inside bloks"); |
} |
|
void doloop(unsigned int typeb) // both short and long loops |
{ |
unsigned int startloc,startloc2; |
int looptok; |
ITOK lootok; |
char *loopbuf; |
signed char delta; |
SINFO lstr; |
int j=0,sline=linenumber; |
unsigned int oaddESP=addESP; |
nexttok(); |
// printf("tok=%u name=%s bufrm=%s\n",tok,itok.name,bufrm); |
expecting(tk_openbracket); |
looptok=tok; |
lootok=itok; |
loopbuf=bufrm; |
bufrm=NULL; |
lstr=strinf; |
strinf.bufstr=NULL; |
// printf("bufrm=%s strinf=%s\n",loopbuf,lstr.bufstr); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
uptdbr(); |
if(dbg&1)KillLastLine(); |
if((tok<tk_charvar||tok>tk_dwordvar)&&tok!=tk_reg&&tok!=tk_reg32 |
&&tok!=tk_beg&&tok!=tk_closebracket) |
preerror(invaliddecrem); |
if(tok!=tk_closebracket){ |
if(typeb!=tk_loop){ |
if(dbg)AddLine(); |
int vop=tok==tk_reg?r16:r32; |
if(typeb==tk_LOOPNZ&&((tok==tk_reg&&itok.number==CX)|| |
(tok==tk_reg32&&itok.number==ECX))&&(!(optimizespeed&&chip>3&&chip<7))){ |
op67(vop); |
outword(0xE3); |
} |
else{ |
if(tok==tk_reg||tok==tk_reg32||tok==tk_beg){ |
if(tok==tk_beg)op(0x84); |
else{ |
op66(vop); |
op(0x85); |
} |
op(0xc0+(unsigned int)itok.number*9); |
} |
else{ |
ITOK htok2; |
htok2.number=0; |
htok2.rm=(am32==FALSE?rm_d16:rm_d32); |
htok2.segm=DS; |
htok2.post=0; |
htok2.sib=(am32==FALSE?CODE16:CODE32); |
htok2.flag=0; |
int razr=r_undef; |
switch(tok){ |
case tk_longvar: |
case tk_dwordvar: |
razr=2; |
case tk_intvar: |
case tk_wordvar: |
razr++; |
case tk_charvar: |
case tk_bytevar: |
razr++; |
} |
outcmp(0,tok,&itok,bufrm,&strinf,tk_number,&htok2,loopbuf,&lstr,razr); |
} |
if(typeb==tk_LOOPNZ)outword(0x74); |
else{ |
if(chip<3){ |
outword(0x0375); // JNZ past jump up |
op(0xE9); |
} |
else{ |
outword(0x840F); |
} |
outword(0); |
if(am32!=FALSE)outword(0); |
} |
} |
} |
nexttok(); //òî ÷òî óìåíüøàåòñÿ |
} |
expecting(tk_closebracket); |
startloc2=outptr; |
if(AlignCycle)AlignCD(CS,aligncycle); |
startloc=outptr; |
docommand(); |
RestoreStack(); |
SetContinueLabel(); |
if(looptok!=tk_closebracket){ |
if(((outptr-startloc)<=(127-3))&&(chip<3||optimizespeed==0)&& |
((looptok==tk_reg&&lootok.number==CX)||(looptok==tk_reg32&&lootok.number==ECX))){ |
delta=(char)(startloc-(outptr+2)); |
if(op67(looptok==tk_reg?r16:r32)!=FALSE)delta--; |
op(0xE2); |
op(delta); /* LOOP 'delta' */ |
} |
else{ |
decit(looptok,&lootok,loopbuf,&lstr); |
if((outptr-startloc)>(unsigned int)(127-2-j)){ /* long jump */ |
if(chip<3){ |
outword(0x0374); // JZ past jump up |
op(0xE9); |
} /* JMP top of loop */ |
else{ |
outword(0x850F); |
if(cpu<3)cpu=3; |
} |
if(am32==FALSE)outword(startloc-(outptr+2)); |
else outdword(startloc-(outptr+4)); |
} |
else{ |
op(0x75); // short jump |
op(startloc-(outptr+1)); |
} /* JNZ 'delta' */ |
} |
} |
else jumploc(startloc);//JMP íà íà÷àëî öèêëà |
if(typeb!=tk_loop){ |
looptok=outptr-startloc2; |
if(typeb==tk_LOOPNZ){ |
if(looptok>127)jumperror(sline,mesLOOPNZ); |
output[startloc2-1]=(unsigned char)looptok; |
} |
else{ |
if(looptok<=127)warningjmp(mesLOOPNZ,sline); |
if(am32==FALSE)*(unsigned short *)&output[startloc2-2]=(unsigned short)looptok; |
else *(unsigned long *)&output[startloc2-4]=(unsigned long)looptok; |
} |
} |
SetBreakLabel(); |
if(usebr[curbr]!=0||useco[curco]!=0||typeb!=tk_loop)clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
if(ESPloc&&am32&&oaddESP!=addESP)warESP(); |
lastcommand=tk_loop; |
} |
|
void GetNameLabel(int type,int num) |
{ |
sprintf((char *)string2,type==tk_break?"BREAK%04X":"CONTINUE%04X",listbr[num]); |
} |
|
void SetBreakLabel() |
{ |
curbr--; |
if(usebr[curbr]!=0){ |
GetNameLabel(tk_break,curbr); |
updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start); |
// clearregstat(); |
} |
} |
|
void SetContinueLabel() |
{ |
curco--; |
if(useco[curco]!=0){ |
GetNameLabel(tk_continue,curco); |
updatecall((unsigned int)updatelocalvar((char *)string2,tk_number,outptr),outptr,procedure_start); |
} |
} |
|
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ |
|
void SaveDataVal(unsigned int ssize,unsigned long long val) |
{ |
switch(ssize){ |
case 1: opd(val); break; |
case 2: outwordd(val); break; |
case 4: outdwordd(val); break; |
case 8: outqwordd(val); break; |
} |
} |
|
long AddVarString() |
{ |
long loop=0; |
int term; |
do{ |
term=itok.flag; |
for(int i=0;i<itok.number;i++){ //ââåñòè ñòðîêó |
opd(string[i]); |
loop++; |
} |
nexttok(); |
}while(tok==tk_string); |
switch(term&3){ |
case zero_term: |
if(term&s_unicod)opd(0); |
opd(0); |
loop++; |
break; |
case dos_term: |
if(term&s_unicod)opd(0); |
opd('$'); |
loop++; |
break; |
} |
return loop; |
} |
|
long initglobalvar(int type,long elements,long ssize,char typev) |
{ |
long loop; |
long long i=0; |
int htok; |
char name[IDLENGTH]; |
nexttok(); |
loop=0; |
if(dbg&2)AddDataLine((tok==tk_string&&typev!=pointer?(char)3:(char)ssize)); |
loopsw: |
htok=tok; |
switch(tok){ //çàïîëíèòü âåëè÷èíàìè |
case tk_apioffset: AddApiToPost(itok.number); nexttok(); break; |
case tk_postnumber: |
(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
itok.flag=0; |
goto cn1; |
case tk_undefofs: |
strcpy(name,itok.name); |
// AddUndefOff(1,itok.name); |
cn1: |
tok=tk_number; |
case tk_minus: |
case tk_number: |
if(type==tk_byte||type==tk_word||type==tk_dword)i+=doconstdwordmath(); |
else if(type==tk_float)i=doconstfloatmath(); |
else if(type==tk_double)i=doconstdoublemath(); |
else if(type==tk_qword)i+=doconstqwordmath(); |
else i+=doconstlongmath(); |
if(tok==tk_plus&&tok2==tk_postnumber&&htok!=tk_undefofs){ |
nexttok(); |
goto loopsw; |
} |
if(elements!=0){ |
for(;loop<elements;loop++){ |
if(postnumflag&f_reloc)AddReloc(); |
if(htok==tk_undefofs)AddUndefOff(3,name); |
SaveDataVal(ssize,i); |
} |
} |
loop=loop*ssize; |
break; |
case tk_string: |
if(typev==pointer){ |
loop=(am32==FALSE?2:4); |
i=addpoststring(DS); |
if(am32==FALSE)outwordd(i); |
else outdwordd(i); |
nexttok(); |
} |
else{ |
loop=AddVarString(); |
if(elements!=0){ |
for(;loop<ssize*elements;loop++){//äîïîëíèòü 0 åñëè êîðîòêàÿ |
opd(aligner); |
} |
} |
} |
break; |
case tk_from: //ñ÷èòàòü ôàéë ñ äàííûìè |
nexttok(); |
loop=dofrom(); |
if(elements!=0){ |
for(;loop<ssize*elements;loop++)opd(aligner); |
} |
nexttok(); |
break; |
case tk_extract: //ñ÷èòàòü ôðàãìåíò ôàéëà ñ äàííûìè |
nexttok(); |
loop=doextract(); |
if(elements!=0){ |
for(;loop<ssize*elements;loop++)opd(aligner); |
} |
break; |
case tk_openbrace: //ìàññèâ äàííûõ |
nexttok(); |
while(tok!=tk_closebrace){ |
htok=tok; |
if(typev==pointer){ |
if(tok==tk_string){ |
i=addpoststring(DS); |
nexttok(); |
} |
else if(tok==tk_number||tok==tk_minus||tok==tk_undefofs){ |
if(tok==tk_undefofs){ |
tok=tk_number; |
strcpy(name,itok.name); |
// AddUndefOff(1,itok.name); |
} |
// else if((itok.flag&f_reloc)!=0)AddReloc(); |
i=doconstdwordmath(); |
} |
else{ |
numexpected(); |
nexttok(); |
} |
if(postnumflag&f_reloc)AddReloc(); |
if(htok==tk_undefofs)AddUndefOff(3,name); |
if(am32==FALSE)outwordd(i); |
else outdwordd(i); |
} |
else{ |
switch(tok){ |
case tk_apioffset: AddApiToPost(itok.number); nexttok(); break; |
case tk_string: |
loop+=AddVarString()/ssize-1; |
break; |
case tk_postnumber: |
(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
itok.flag=0; |
goto cn2; |
case tk_undefofs: |
strcpy(name,itok.name); |
// AddUndefOff(1,itok.name); |
cn2: |
tok=tk_number; |
case tk_number: |
case tk_minus: |
if(type==tk_byte||type==tk_word||type==tk_dword)i=doconstdwordmath(); |
else if(type==tk_float)i=doconstfloatmath(); |
else if(type==tk_double)i=doconstdoublemath(); |
else if(type==tk_qword)i=doconstqwordmath(); |
else i=doconstlongmath(); |
// if((postnumflag&f_reloc)!=0)AddReloc(); |
if((postnumflag&f_reloc)!=0)AddReloc(); |
if(htok==tk_undefofs)AddUndefOff(3,name); |
SaveDataVal(ssize,i); |
break; |
default: |
numexpected(); |
nexttok(); |
break; |
} |
} |
loop++; |
if(tok==tk_closebrace)break; |
expecting(tk_camma); |
} |
if(elements!=0){ |
for(;loop<elements;loop++)SaveDataVal(ssize,aligner); |
} |
loop=loop*ssize; |
nexttok(); |
break; |
default: |
// printf("tok=%d\n",tok); |
numexpected(); nexttok(); break; |
} |
return loop; |
} |
|
void AddPostData(unsigned int loop) |
{ |
if(dynamic_flag==0){ |
unsigned int longpostsize=loop+postsize; |
if(am32==FALSE&&longpostsize>0xFFFFL)tobigpost(); |
else postsize=longpostsize; |
} |
} |
|
void labelindata() |
{ |
//idrec *varrec; |
FindOff((unsigned char *)itok.name,DS); |
tok=tk_number; |
itok.number=outptrdata; |
itok.segm=DS; |
string[0]=0; |
if(FixUp)itok.flag=f_reloc; |
/*varrec=*/addtotree(itok.name); |
/*varrec->count=*/FindOff((unsigned char *)itok.name,DS); |
nexttok(); |
nexttok(); |
} |
|
void globalvar() /* both initialized and unitialized combined */ |
{ |
long size,loop,i,elements,ssize; |
char done=0,typev; |
char var_name[IDLENGTH]; |
int type=itok.rm,typebak; //òèï ïåðåìåííîé |
unsigned int flag,fflag=itok.flag,dynamic; |
unsigned int npointr=itok.npointr; |
int count; |
idrec *varrec; |
size=typesize(type); //ðàçìåð ïåðåìåííîé |
if(FixUp)fflag|=f_reloc; |
typebak=type; |
while(tok!=tk_eof&&done==0){ |
int nnpointr=0; |
typev=variable; |
ssize=size; |
flag=fflag; |
type=typebak; |
// printf("type=%d\n",type); |
if(tok==tk_far){ |
flag|=f_far; |
nexttok(); |
} |
while(tok==tk_mult){ //óêàçàòåëü |
npointr++; |
nexttok(); |
} |
if(tok==tk_openbracket){ |
nexttok(); |
while(tok==tk_mult){ //óêàçàòåëü íà ïðîöåäóðó |
nnpointr++; |
nexttok(); |
} |
} |
if(npointr){ |
if((flag&f_far)!=0||am32!=FALSE)ssize=4; |
else ssize=2; |
typev=pointer; |
type=am32==FALSE?tk_word:tk_dword; |
} |
// printf("tok=%d %s\n",tok,itok.name); |
switch(tok){ |
case tk_id: |
case tk_ID: |
if(tok2==tk_openbracket||nnpointr){ |
if(npointr)type=am32==FALSE?tk_word:tk_dword; |
declare_procedure(flag,type,nnpointr); |
break; |
} |
strcpy(var_name,itok.name); //èìÿ ïåðåìåííîé |
elements=1; |
nexttok(); |
if(tok==tk_openblock){ //[ |
nexttok(); |
if(tok==tk_closeblock){//íåèçâåñòíîå ÷èñëî ýëåìåíòîâ |
elements=0; |
nexttok(); |
} |
else{ |
CheckMinusNum(); |
if(tok!=tk_number){ |
numexpected(); |
nexttok(); |
} |
else{ |
elements=doconstlongmath(); //÷èñëî ýëåìåíòîâ |
expecting(tk_closeblock); |
} |
} |
} |
if(type==tk_void){ |
preerror("type 'void' not use for declare variables"); |
break; |
} |
dynamic=FALSE; |
if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){ //= èíèöèàëèçèðîâàíàÿ ïåðåìåííàÿ |
if((flag&f_extern))preerror("extern variable do not initialize at declare"); |
i=tok; |
itok.type=tp_gvar;// 11.07.05 21:56 tp_ucnovn; |
SetNewTok(type,typev); |
if(useStartup==TRUE&&i!=tk_assign&&SaveStartUp(size*elements,var_name)!=FALSE){ |
if(elements==0)ZeroMassiv(); //îøèáêà |
tok=i; |
break; |
} |
if(alignword&&ssize&&(!dynamic_flag))alignersize+=AlignCD(DS,ssize); |
itok.number=dynamic_flag==0?outptrdata:0; |
itok.segm=(comfile==file_rom&&modelmem==TINY?CS:DS); |
itok.flag=flag; |
// itok.post=dynamic; |
itok.size=elements*ssize; |
itok.rm=(am32==FALSE?rm_d16:rm_d32); |
itok.npointr=(unsigned short)npointr; |
|
varrec=addtotree(var_name); |
if((count=FindOff((unsigned char *)var_name,DS))==0){ |
if(dynamic_flag)dynamic=DYNAMIC_VAR; |
} |
else if(dynamic_flag)dynamic=USED_DIN_VAR; |
if(i!=tk_assign){ |
if(elements==0)ZeroMassiv(); |
else if(notpost==TRUE){ |
for(loop=0;loop<elements;loop++)SaveDataVal(ssize,aligner); |
loop=loop*ssize; |
varrec->recsize=loop; |
datasize+=loop; |
} |
tok=i; |
break; |
} |
if(dynamic){ |
varrec->sbuf=dynamic_var(); |
varrec->recpost=dynamic; |
} |
else{ |
loop=initglobalvar(type,elements,ssize,typev); |
varrec->recsize=loop; |
datasize+=loop; |
} |
varrec->count=count; |
} |
else{ |
if(elements==0){ |
ZeroMassiv(); |
break; |
} |
if(CheckUseAsUndef((unsigned char *)var_name)==0&&dynamic_flag)dynamic=TRUE; |
switch(tok){ //íåèíèöèàëèçèðîâàííûå |
default: expected(';'); |
case tk_semicolon: done=1;// ; |
case tk_camma: //, post global type |
itok.type=tp_postvar;//11.07.05 21:57 tp_ucnovn; |
SetNewTok(type,typev); |
if((flag&f_extern)==0&&useStartup==TRUE&&dynamic==0){ |
if(SaveStartUp(ssize*elements,var_name)!=FALSE){ |
nexttok(); |
break; |
} |
} |
if((flag&f_extern)==0&&alignword&&dynamic==0){ //âûðîâíÿòü íà ÷åòíûé àäðåñ |
if(ssize==2){ |
if(postsize%2==1)postsize++; |
} |
else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4); |
} |
count=FindOff((unsigned char *)var_name,VARPOST); |
itok.post=dynamic+1; |
itok.segm=DS; |
loop=elements*ssize; |
itok.number=(flag&f_extern)==0?postsize:externnum++; |
itok.flag=flag; |
itok.size=loop; |
itok.rm=(am32==FALSE?rm_d16:rm_d32); |
itok.npointr=(unsigned short)npointr; |
varrec=addtotree(var_name); |
varrec->count=count; |
if((flag&f_extern)==0)AddPostData(loop); |
nexttok(); |
break; |
} |
} |
break; |
case tk_undefproc: |
if(tok2==tk_openbracket||nnpointr){ |
if(npointr)type=am32==FALSE?tk_word:tk_dword; |
declare_procedure(flag,type,nnpointr); |
break; |
} |
case tk_proc: |
case tk_floatvar: |
case tk_dwordvar: |
case tk_longvar: |
case tk_charvar: |
case tk_intvar: |
case tk_bytevar: |
case tk_pointer: |
case tk_wordvar: idalreadydefined(); nexttok(); break; |
default: expected(';'); |
case tk_semicolon: done=1; |
case tk_camma: nexttok(); break; |
} |
npointr=0; |
} |
dopoststrings(); |
} |
|
void SetNewTok(int type,int typev) |
{ |
switch(typev){ |
case variable: |
if(type>=tk_char&&type<=tk_double)tok=type+(tk_charvar-tk_char); |
break; |
case pointer: |
// if(type>=tk_void&&type<=tk_float){ |
tok=tk_pointer; |
itok.type=(unsigned short)type; |
// } |
break; |
} |
} |
|
int SaveStartUp(int size,char *var_name) |
{ |
int i=0; |
if((startStartup+size)<=endStartup){ |
if(alignword){ //âûðîâíÿòü íà ÷åòíûé àäðåñ |
if(size==2){ |
if(startStartup%2==1)i=1; |
} |
else if(size==4&&startStartup%4!=0)i=4-(startStartup%4); |
} |
if((startStartup+size+i)<=endStartup){ |
startStartup+=i; |
itok.number=startStartup; |
itok.segm=DS; |
itok.flag=0; |
itok.post=0; |
itok.rm=(am32==FALSE?rm_d16:rm_d32); |
itok.type=tp_ucnovn; |
addtotree(var_name); |
startStartup+=size; |
return TRUE; |
} |
} |
return FALSE; |
} |
|
/* ======= ñòàðò çàãîëîâêà ïðîöåäóðû ======== */ |
|
void setuprm() |
{ |
itok.rm=returntype=(itok.rm==tokens?am32==FALSE?tk_word:tk_dword:itok.rm); |
if(itok.npointr)itok.rm=returntype=(am32==FALSE?tk_word:tk_dword); |
} |
|
void eaxToFloat(int reg=AX) |
{ |
int next=1; |
CheckMinusNum(); |
if(itok2.type==tp_opperand){ //ñîñòàâíîå |
doeaxfloatmath(tk_reg32,reg); |
next=0; |
} |
else{ |
switch(tok){ |
case tk_number: |
if(itok.rm==tk_double)itok.fnumber=itok.dnumber; |
else if(itok.rm!=tk_float){ |
float temp=itok.number; |
*(float *)&itok.number=temp; |
} |
op66(r32); |
op(0xb8+reg); // MOV EAX,# |
outdword(itok.number); |
break; |
case tk_floatvar: |
if(reg==AX&&itok.rm==rm_d16&&itok.sib==CODE16){ |
op66(r32); |
outseg(&itok,1); |
op(0xA1); |
outword((unsigned int)itok.number); |
} |
else{ |
CheckAllMassiv(bufrm,4,&strinf); |
op66(r32); |
outseg(&itok,2); |
op(0x8B); |
op(itok.rm+reg*8); |
outaddress(&itok); |
} |
break; |
default: |
if(doeaxfloatmath(tk_reg32,reg)!=tk_reg32&®!=AX){ |
if(!am32)Leave(); |
op66(r32); |
op(0x89); |
op(0xc0+reg); |
} |
next=0; |
} |
} |
if(next)nexttok(); |
} |
|
void CalcRegPar(int reg,int def,char **ofsstr) |
{ |
char signflag=0; |
int razr; |
unsigned char oinline=useinline; |
useinline=0; |
// if(*ofsstr)puts(*ofsstr); |
if(tok!=tk_camma){ |
if(tok==tk_openbracket){ |
nexttok(); |
if(tok>=tk_char&&tok<=tk_double)def=tok; |
nexttok(); |
expectingoperand(tk_closebracket); |
} |
if(tok>=tk_char&&tok<=tk_double){ |
def=tok; |
getoperand(); |
} |
if(tok==tk_string){ |
op(0xB8+reg); |
if(am32==FALSE)outword(addpoststring()); |
else outdword(addpoststring()); |
nexttok(); |
razr=(am32==FALSE?r16:r32); |
} |
else if(tok==tk_floatvar)eaxToFloat(reg); |
else{ |
switch(def){ |
case tk_int: signflag=1; |
case tk_word: |
if(reg==AX)do_e_axmath(signflag,r16,ofsstr); |
else getintoreg(reg,r16,signflag,ofsstr); |
razr=r16; |
break; |
case tk_char: signflag=1; |
case tk_byte: |
if(reg==AX)doalmath(signflag,ofsstr); |
else{ |
getintobeg(reg,ofsstr); |
dobegmath(reg); |
} |
razr=r8; |
break; |
case tk_long: signflag=1; |
case tk_dword: |
if(reg==AX)do_e_axmath(signflag,r32,ofsstr); |
else getintoreg(reg,r32,signflag,ofsstr); |
razr=r32; |
break; |
case tk_float: |
eaxToFloat(reg); |
razr=r32; |
break; |
case tk_qword: |
getintoreg64(reg); |
doregmath64(reg); |
razr=r64; |
break; |
case tokens: |
razr=(am32==FALSE?r16:r32); |
if(reg==AX)do_e_axmath(0,razr,ofsstr); |
else getintoreg(reg,razr,signflag,ofsstr); |
break; |
} |
} |
AddRegistr(razr,reg); |
// printf("%08X\n",reg); |
} |
useinline=oinline; |
} |
|
int GetTypeParam(char c) |
{ |
switch(c){ |
case 'B': return tk_byte; |
case 'W': return tk_word; |
case 'D': return tk_dword; |
case 'C': return tk_char; |
case 'I': return tk_int; |
case 'L': return tk_long; |
case 'F': return tk_float; |
case 'A': return tk_multipoint; |
case 'Q': return tk_qword; |
case 'E': return tk_double; |
case 'S': return tk_fpust; |
case 'T': return tk_struct; |
case 'U': return tokens; |
default: |
extraparam(); |
// printf("%c\n",c); |
return 0; |
} |
} |
|
void doregparams() |
{ |
int i=0; |
char *ofsstr=NULL; |
int razr; |
int retreg; |
ClearRegister(); |
if(tok!=tk_openbracket)expected('('); |
while(tok2==tk_camma){ |
nexttok(); |
i++; |
} |
ofsstr=GetLecsem(tk_camma,tk_closebracket); |
getoperand(); |
if(tok!=tk_closebracket){ |
if(strlen(param)!=0){ |
int def; |
char *oparam=BackString(param); |
for(;;){ |
while(tok==tk_camma){ |
if(ofsstr)free(ofsstr); |
ofsstr=GetLecsem(tk_camma,tk_closebracket); |
getoperand(); |
} |
if((def=GetTypeParam(oparam[i++]))==0){ |
nexttok(); |
break; |
} |
if(def==tk_qword){ |
int c1,c2; |
c1=oparam[i++]-0x30; |
c2=oparam[i++]-0x30; |
retreg=c1|(c2*256); |
// printf("%08X\n",retreg); |
} |
else retreg=oparam[i++]-0x30; |
if(ofsstr){ |
if((razr=getrazr(def))!=r64){ |
int retr; |
if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){ |
GetEndLex(tk_camma,tk_closebracket); |
if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr); |
nexttok(); |
goto endparam; |
} |
} |
} |
if(def==tk_fpust)float2stack(retreg); |
else CalcRegPar(retreg,def,&ofsstr); |
endparam: |
if(ofsstr&&razr!=r64){ |
IDZToReg(ofsstr,retreg,razr); |
free(ofsstr); |
ofsstr=NULL; |
} |
if(tok!=tk_camma){ |
if(tok!=tk_closebracket)expected(')'); |
if(oparam[i]!=0)missingpar(); |
break; |
} |
} |
free(oparam); |
} |
else{ |
char regpar[6]={AX,BX,CX,DX,DI,SI}; |
for(;i<6;i++){ |
if(tok==tk_camma){ |
if(ofsstr)free(ofsstr); |
ofsstr=GetLecsem(tk_camma,tk_closebracket); |
getoperand(); |
if(tok==tk_camma)continue; |
} |
retreg=regpar[i]; |
if(ofsstr&&tok!=tk_camma){ |
razr=(am32==FALSE?r16:r32); |
int retr; |
if((retr=CheckIDZReg(ofsstr,retreg,razr))!=NOINREG){ |
GetEndLex(tk_camma,tk_closebracket); |
if(retr!=SKIPREG)GenRegToReg(retreg,retr,razr); |
nexttok(); |
goto endparam1; |
} |
} |
CalcRegPar(retreg,tokens,&ofsstr); |
endparam1: |
if(ofsstr){ |
IDZToReg(ofsstr,retreg,razr); |
free(ofsstr); |
ofsstr=NULL; |
} |
if(tok!=tk_camma){ |
if(tok!=tk_closebracket)expected(')'); |
break; |
} |
} |
} |
setzeroflag=FALSE; |
} |
if(ofsstr)free(ofsstr); |
} |
|
int CheckUses() |
{ |
int i; |
int regs=0; |
int bracket=FALSE; |
memset((SAVEREG *)psavereg,0,sizeof(SAVEREG)); |
if(tok==tk_openbracket){ |
if(stricmp(itok2.name,"uses")==0){ |
bracket=TRUE; |
nexttok(); |
} |
else return 0; |
} |
if(stricmp(itok.name,"uses")==0){ |
nexttok(); |
while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){ |
i=r32; |
switch(tok){ |
case tk_beg: |
if(itok.number>3)itok.number-=4; |
i=(am32+1)*2; |
break; |
case tk_reg: |
if(!am32)i=r16; |
break; |
} |
regs=regs|(1<<itok.number); |
psavereg->reg[itok.number]=i; |
i=1; |
if((am32&&i==r16)||(am32==0&&i==r32))i=2; |
psavereg->size+=i; |
nexttok(); |
if(tok==tk_camma)nexttok(); |
} |
if(strcmp(itok.name,"allregs")==0){ |
psavereg->size=1; |
psavereg->all=1; |
regs=dEAX|dEBX|dECX|dEDX|dEBP|dEDI|dESI; |
nexttok(); |
} |
} |
if(bracket)expecting(tk_closebracket); |
return regs; |
} |
|
void Enter() |
{ |
if(ESPloc==FALSE||am32==FALSE){ |
op(0x55); //push bp |
outword(0xe589);//mov bp,sp |
} |
} |
|
void setproc(int defflag) |
{ |
char *bstring; |
unsigned char oinline,ooptimizespeed; |
ITOK otok; |
unsigned int i; |
int regs=0; |
unsigned char oESPloc=ESPloc; |
int startline=linenumber; |
unsigned int oregidx; |
|
clearregstat(); |
addESP=inlineflag=0; |
oinline=useinline; |
ooptimizespeed=optimizespeed; |
oregidx=*(unsigned int *)&idxregs; |
current_proc_type=itok.flag; |
|
if(itok.flag&f_extern)notexternfun(); //new 18.04.07 12:20 |
// printf("%s tok=%d flag=%08X\n",itok.name,tok,itok.flag); |
|
tok=lastcommand=tk_proc; |
itok.number=outptr; |
if(itok.segm<NOT_DYNAMIC)itok.segm=DYNAMIC_SET; |
setuprm(); |
// printf("rm=%d %s\n",itok.rm,itok.name); |
if(defflag){ //ðàíåå óæå áûëè âûçîâû |
// updatecall(updatetree(),(unsigned int)itok.number,0); |
regs=itok.post; |
if(updatecall(updatetree(),(unsigned int)itok.number,0)==-1&& |
strcmp(itok.name,mesmain)==0/*&&jumptomain!=CALL_NONE*/){ |
itok.number=outptr=outptr-(jumptomain==CALL_SHORT?2:am32==FALSE?3:5); |
if(dbg){ |
KillLastLine(); |
KillLastLine(); |
AddLine(); |
} |
updatetree(); |
} |
} |
else{ //èíà÷å äîáàâèòü â äåðåâî |
string[0]=0; |
itok.type=tp_ucnovn; |
addtotree(itok.name); |
} |
// puts(itok.name); |
if((i=FindOff((unsigned char *)itok.name,CS))!=0){ |
itok.rec->count=i; |
} |
bstring=BackString((char *)string); |
otok=itok; |
if(strcmp(mesmain,otok.name)==0){ |
if(startuptomain==TRUE&&comfile==file_com)doprestuff(); |
if(numdomain!=0){ |
for(i=0;i<numdomain;i++){ |
strcpy(itok.name,domain+i*IDLENGTH); |
tok=tk_ID; |
searchvar(itok.name,0); |
switch(tok){ |
case tk_ID: |
case tk_id: |
tobedefined(am32==FALSE?CALL_NEAR:CALL_32,tk_void); |
(postbuf+posts-1)->loc=outptr+1; |
callloc0(); /* produce CALL [#] */ |
break; |
case tk_declare: |
tok=tk_undefproc; |
updatetree(); |
case tk_undefproc: |
addacall(itok.number,(unsigned char)((itok.flag&f_extern)!=0?CALL_EXT:(am32!=FALSE?CALL_32:CALL_NEAR))); |
callloc0(); /* produce CALL [#] */ |
break; |
case tk_proc: |
if(itok.flag&f_far)op(0x0e); //push cs |
if(itok.segm<NOT_DYNAMIC){ |
addacall(itok.number,(unsigned char)(am32!=FALSE?CALL_32:CALL_NEAR)); |
itok.number=0; |
} |
callloc(itok.number); |
break; |
default: |
preerror("impossible type for startup function"); |
break; |
} |
} |
numdomain=0; |
free(domain); |
} |
} |
nextexpecting2(tk_openbracket); |
startblock(); |
if(searchteg&&(!(current_proc_type&f_static))&&(current_proc_type&f_typeproc)!=tp_pascal)AddThis(); |
if(tok!=tk_closebracket){ |
if((current_proc_type&f_typeproc)!=tp_fastcall){ |
declareparams(); |
if(otok.type==tp_declare&&defflag&&strcmp(bstring,param)!=0){ |
// printf("old=%s new=%s\n",bstring,param); |
redeclare(otok.name); |
} |
// if(bstring[0]!=0&&bstring[0]!='A'&&strcmp(bstring,param)!=0)redeclare(); |
} |
else{ |
declareparamreg(); |
} |
if(bstring)free(bstring); |
bstring=BackString((char *)param); |
} |
else if((current_proc_type&f_typeproc)!=tp_fastcall&&bstring[0]!=0){ |
if(bstring[0]!='V'&&bstring[0]!='A'){ |
redeclare(otok.name); |
// puts(bstring); |
} |
} |
|
strcpy((char *)string,bstring); |
itok=otok; |
tok=tk_proc; |
updatetree(); |
|
if(searchteg&&(!(current_proc_type&f_static))&&(current_proc_type&f_typeproc)==tp_pascal)AddThis(); |
nexttok(); |
blockproc=TRUE; |
// printf("tok=%d\n",tok); |
if(tok==tk_inline){ |
inlineflag=1; |
nexttok(); |
} |
else if(paramsize)Enter(); // PUSH BP MOV BP,SP |
if(tok==tk_colon&&(current_proc_type&fs_constructor)!=0){ |
do{ |
AddBackBuf(inptr2,cha2); |
}while(tok==tk_camma); |
nexttok(); |
} |
regs|=CheckUses(); |
CorrectParamVar(); |
if(tok!=tk_openbrace)declarelocals(0,inlineflag); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
// numblocks++; //íà ýòîì ìåñòå äëÿ ðàíåãî îïðåäåëåíèÿ ::var |
expecting(tk_openbrace); |
declarelocals(1,inlineflag); |
retproc=FALSE; |
if(paramsize||localsize/*||(lstructlist!=NULL)*/){ |
initBP=1; |
if(inlineflag)warninline(); |
} |
|
#ifdef __NEWLEX__ |
doblockstart(otok.name); |
#endif |
doblock2(); // do proc |
if(current_proc_type&fs_destructor){ |
elementteg *bazael=searchteg->baza; |
for(i=0;i<searchteg->numoper;i++){ |
if((bazael+i)->tok==tk_baseclass)CallDestructor((structteg *)(bazael+i)->rec); |
} |
} |
i=numreturn; |
setreturn(); |
if(inlineflag==0&&retproc==FALSE&&(i||(lastcommand!=tk_goto&&lastcommand!=tk_GOTO)))leaveproc(); |
endblock(); |
initBP=0; |
strcpy((char *)string,bstring); |
itok=otok; |
tok=tk_proc; |
itok.size=outptr-procedure_start; |
itok.rec->recpost=regs; |
// printf("reg=%08X set=%s\n",regs,itok.name); |
#ifdef OPTVARCONST |
if(inlineflag)itok.flag|=f_useidx; |
#endif |
updatetree(); |
if(mapfile)mapfun(startline); |
i=linenumber; |
linenumber=startline; |
killlocals(); |
linenumber=i; |
free(bstring); |
optimizespeed=ooptimizespeed; |
useinline=oinline; |
*(unsigned int *)&idxregs=oregidx; |
if(searchteg)searchteg=NULL; |
blockproc=FALSE; |
ESPloc=oESPloc; |
nexttok(); |
} |
|
void insertproc(/*int sizepar*/) |
{ |
unsigned char oinline,ooptimizespeed; |
struct treelocalrec *otlr; |
struct structteg *olteglist; |
//struct idrec *olstructlist; |
struct idrec *rec; |
unsigned int oparamsize; |
unsigned int olocalsize; |
unsigned char oinsertmode; |
unsigned int onumblocks; //íîìåð âëîæåííîãî áëîêà |
unsigned int osizestack; |
RETLIST *olistreturn; |
unsigned int onumreturn; |
int oinlineflag; |
SAVEREG *osavr; |
unsigned int oaddESP=addESP; |
addESP=0; |
clearregstat(); |
osavr=psavereg; |
psavereg=(SAVEREG*)MALLOC(sizeof(SAVEREG)); |
oinsertmode=insertmode; |
insertmode=TRUE; //ôëàã ðåæèìà âñòàâêè |
oinline=useinline; |
ooptimizespeed=optimizespeed; |
current_proc_type=itok.flag; |
rec=itok.rec; |
otlr=tlr; |
olteglist=ltegtree; |
// olstructlist=lstructlist; |
oinlineflag=inlineflag; |
osizestack=sizestack; |
sizestack=0; |
tlr=NULL; |
ltegtree=NULL; |
// lstructlist=0; |
oparamsize=paramsize; |
olocalsize=localsize; |
onumblocks=numblocks; |
olistreturn=listreturn; |
onumreturn=numreturn; |
paramsize=0; |
localsize=0; |
numblocks=0; //íîìåð âëîæåííîãî áëîêà |
listreturn=NULL; |
numreturn=0; |
inlineflag=0; |
nextexpecting2(tk_openbracket); |
if(tok!=tk_closebracket){ |
if((current_proc_type&f_typeproc)!=tp_fastcall)declareparams(); |
else declareparamreg(); |
} |
CorrectParamVar(); |
nexttok(); |
if(tok==tk_inline){ |
nexttok(); |
inlineflag=1; |
expecting(tk_openbrace); |
} |
else{ |
if((current_proc_type&f_typeproc)!=tp_fastcall&¶msize>0)Enter(); // PUSH BP MOV BP,SP |
rec->recpost|=CheckUses(); |
if(tok!=tk_openbrace)declarelocals(0); |
expecting(tk_openbrace); |
declarelocals(1); |
} |
retproc=FALSE; |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
startblock(); |
doblock2(); |
sizestack=osizestack; // do proc |
setreturn(); |
endblock(); |
RestoreSaveReg(); |
if(inlineflag==0&&(localsize||paramsize)&&(ESPloc==FALSE||am32==FALSE))Leave(); |
killlocals(/*0*/); |
optimizespeed=ooptimizespeed; |
useinline=oinline; |
paramsize=oparamsize; |
localsize=olocalsize; |
tlr=otlr; |
ltegtree=olteglist; |
// lstructlist=olstructlist; |
insertmode=oinsertmode; |
numblocks=onumblocks; |
listreturn=olistreturn; |
numreturn=onumreturn; |
inlineflag=oinlineflag; |
free(psavereg); |
psavereg=osavr; |
addESP=oaddESP; |
// nexttok(); |
// printf("tok=%d\n",tok); |
} |
|
void AddTypeVar(int type,int pos) |
{ |
switch(type){ |
case tk_char: |
param[pos]='C'; |
break; |
case tk_byte: |
param[pos]='B'; |
break; |
case tk_int: |
param[pos]='I'; |
break; |
case tk_word: |
param[pos]='W'; |
break; |
case tk_long: |
param[pos]='L'; |
break; |
case tk_dword: |
param[pos]='D'; |
break; |
case tk_float: |
param[pos]='F'; |
break; |
case tk_qword: |
param[pos]='Q'; |
break; |
case tk_double: |
param[pos]='E'; |
break; |
|
} |
} |
|
void declareparamreg() /* declare procedure parameters */ |
{ |
int i=0,num=1; |
unsigned char j=0; |
do{ |
if(tok>=tk_char&&tok<=tk_double){ |
AddTypeVar(tok,i++); |
nexttok(); |
j=1; |
} |
else{ |
switch(tok){ |
case tk_beg: |
if(j==0)param[i++]='B'; |
param[i++]=(char)(itok.number+0x30); |
j=0; |
break; |
case tk_reg: |
if(j==0)param[i++]='W'; |
param[i++]=(char)(itok.number+0x30); |
j=0; |
break; |
case tk_reg32: |
if(j==0)param[i++]='D'; |
param[i++]=(char)(itok.number+0x30); |
j=0; |
break; |
case tk_reg64: |
param[i++]='Q'; |
param[i++]=(char)((itok.number&255)+0x30); |
param[i++]=(char)((itok.number/256)+0x30); |
j=0; |
break; |
case tk_fpust: |
param[i++]='S'; |
param[i++]=(char)(itok.number+0x30); |
j=0; |
break; |
case tk_closebracket: |
if(j==0)goto endproc; |
default: edpip(num); |
} |
nexttok(); |
if(tok==tk_camma){ |
if(j!=0){ |
edpip(num); |
param[i++]='0'; |
j=0; |
} |
nexttok(); |
} |
} |
num++; |
}while(tok!=tk_closebracket); |
endproc: |
if(j!=0){ |
edpip(num-1); |
param[i++]='0'; |
} |
param[i]=0; |
} |
|
void AddMultiPoint(int pos) |
{ |
param[pos]='A'; |
nexttok(); |
if(tok!=tk_closebracket)SwTok(tk_closebracket); |
} |
|
void declareparamstack() /* declare procedure parameters */ |
{ |
int i=0,num=1; |
unsigned char j=0; |
/* |
1 - îáúÿâëåí òèï |
2 - áûëà çàïÿòàÿ |
3 - áûëà òî÷êà ñ çàïÿòîé |
4 - |
5 - áûë èäåíòèôèêàòîð |
6 - òèï void |
*/ |
int typevar=tk_multipoint; |
structteg *tteg=NULL; |
int size; |
do{ |
if(tok==tk_struct)nexttok(); |
if(tok>=tk_char&&tok<=tk_double){ |
if(j>3||j==1)edpip(num); |
j=1; |
typevar=tok; |
nexttok(); |
} |
else if((tteg=FindTeg(TRUE))!=NULL){ |
size=Align(tteg->size,(am32+1)*2); |
// printf("%s size=%u\n",itok.name,size); |
j=1; |
typevar=tk_struct; |
nexttok(); |
} |
while(tok==tk_mult){ |
param[i++]='*'; |
nexttok(); |
} |
if(tok==tk_camma){ |
if(j==1){ |
if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); |
else AddTypeVar(typevar,i++); |
} |
else if(j!=5)edpip(num); |
j=2; |
num++; |
} |
else if(tok==tk_semicolon){ |
if(j==1){ |
if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); |
else AddTypeVar(typevar,i++); |
} |
else if(j!=5)edpip(num); |
j=3; |
num++; |
} |
else if(tok==tk_multipoint){ |
AddMultiPoint(i++); |
break; |
} |
else if(tok==tk_closebracket){ |
if(j==0)param[i++]='A'; |
else if(j==1){ |
if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); |
else AddTypeVar(typevar,i++); |
} |
else if(j<4)edpip(num); |
break; |
} |
else if(tok==tk_void){ |
if(j!=0)edpip(num); |
param[i++]='V'; |
j=6; |
} |
else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){ |
if(j==1){ |
if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); |
else AddTypeVar(typevar,i++); |
} |
else if(j<4){ |
switch(tok){ |
case tk_beg: param[i++]='B'; break; |
case tk_reg: param[i++]='W'; break; |
case tk_reg32: param[i++]='D'; break; |
case tk_fpust: param[i++]='S'; break; |
case tk_reg64: |
param[i++]='Q'; |
param[i++]=(char)((itok.number&255)+0x30); |
itok.number/=256; |
break; |
} |
} |
else edpip(num); |
param[i++]=(char)(itok.number+0x30); |
j=5; |
} |
else{ |
if(j==1||j==2){ |
if(typevar==tk_struct)i+=sprintf(¶m[i],"T%u",size); |
else AddTypeVar(typevar,i++); |
} |
else edpip(num); |
j=5; |
} |
nexttok(); |
}while(tok!=tk_eof); |
param[i]=0; |
// puts(param); |
} |
|
void CorrectParamVar() |
{ |
unsigned int addnum; |
int fspin; |
struct localrec *ptr; |
if(paramsize==0)return; |
if(insertmode)addnum=0; //ret-address |
else addnum=2; |
if(ESPloc==FALSE||am32==FALSE)addnum+=2; //EBP |
if((current_proc_type&f_far))addnum+=2;// move over seg on stack |
if(am32)addnum*=2; |
if((current_proc_type&f_typeproc)==tp_cdecl||(current_proc_type&f_typeproc)==tp_stdcall)fspin=FALSE; |
else fspin=TRUE; |
treelocalrec *ntlr=tlr; |
while(ntlr&&ntlr->level>1)ntlr=ntlr->next; |
for(ptr=ntlr->lrec;;ptr=ptr->rec.next){ |
if(ptr->rec.type==tp_paramvar){ |
if(fspin)ptr->rec.recnumber=paramsize-ptr->rec.recnumber-Align(ptr->rec.recsize,am32==FALSE?2:4); |
ptr->rec.recnumber+=addnum; |
} |
if(ptr->rec.next==NULL)break; |
} |
} |
|
void declareparams() /* declare procedure parameters */ |
{ |
int paramtok,sparamtok,i=0,type; |
char flag=33; |
int numpointr; |
localrec *lrec; |
structteg *tteg=NULL,*nteg; |
do{ |
if(flag!=33)nexttok(); |
flag=1; |
if(tok==tk_multipoint){ |
AddMultiPoint(i++); |
break; |
} |
if(tok==tk_void){ |
param[i++]='V'; |
nexttok(); |
if(tok!=tk_closebracket)SwTok(tk_closebracket); |
break; |
} |
if(tok>=tk_char&&tok<=tk_double){ |
type=tok; |
SetNewTok(tok,variable); |
paramtok=tok; |
} |
else if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust)flag=3; |
else{ |
if(tok==tk_struct)nexttok(); |
if((tteg=FindTeg(TRUE))!=NULL)paramtok=tk_struct; |
else{ |
datatype_expected(); |
flag=0; |
nexttok(); |
} |
} |
if(flag){ |
do{ |
numpointr=0; |
skipfind=TRUE; |
if(flag!=3)nexttok(); |
while(tok==tk_mult){ |
nexttok(); |
numpointr++; |
param[i++]='*'; |
} |
if(tok==tk_id||tok==tk_ID){ //ïðîâåðèòü íà òèïû îïðåäåëåííûå ÷åðåç define |
skipfind=FALSE; |
int otok=tok; |
searchtree(&ptok,&otok,string); |
if(otok>=tk_char&&otok<=tk_double){ |
tok=otok; |
itok=ptok; |
} |
skipfind=TRUE; |
} |
if(tok==tk_struct){ |
nexttok(); |
if((tteg=FindTeg(TRUE))!=NULL){ |
paramtok=tk_struct; |
nexttok(); |
} |
else{ |
edpip(); |
nexttok(); |
goto endparam1; |
} |
} |
else { |
if((nteg=FindTeg(TRUE))!=NULL){ |
tteg=nteg; |
paramtok=tk_struct; |
nexttok(); |
} |
else{ |
if(tok>=tk_char&&tok<=tk_double){ |
type=tok; |
SetNewTok(tok,variable); |
paramtok=tok; |
nexttok(); |
while(tok==tk_mult){ |
nexttok(); |
numpointr++; |
param[i++]='*'; |
} |
flag=2; |
} |
skipfind=FALSE; |
if(tok==tk_beg||tok==tk_reg||tok==tk_reg32||tok==tk_reg64||tok==tk_fpust){ |
if(flag==2)AddTypeVar(type,i++); |
else{ |
switch(tok){ |
case tk_beg: param[i++]='B'; break; |
case tk_reg: param[i++]='W'; break; |
case tk_reg32: param[i++]='D'; break; |
case tk_fpust: param[i++]='S'; break; |
case tk_reg64: |
param[i++]='Q'; |
param[i++]=(char)((itok.number&255)+0x30); |
itok.number/=256; |
break; |
} |
} |
param[i++]=(unsigned char)(itok.number+0x30); |
flag=1; |
goto endparam1; |
} |
} |
} |
sparamtok=paramtok; |
if(tok==tk_multipoint){ |
AddMultiPoint(i++); |
break; |
} |
if(tok!=tk_ID&&tok!=tk_id){ |
idalreadydefined(); |
break; |
} |
int lsize; |
if(am32)lsize=4; |
else{ |
lsize=2; |
if(sparamtok>=tk_longvar&&sparamtok<=tk_floatvar&&numpointr==0) |
lsize+=2;//add 2 more bytes |
} |
if((sparamtok==tk_qwordvar||sparamtok==tk_doublevar)&&numpointr==0)lsize=8; |
AddTypeVar(type,i++); |
if(sparamtok==tk_struct){ |
//idrec *newrec,*trec; |
lsize=Align(tteg->size,(am32+1)*2); |
i+=sprintf(¶m[i],"T%u",lsize); |
// newrec=(struct idrec *)MALLOC(sizeof(struct idrec)); |
// if(lstructlist==NULL)lstructlist=newrec; |
// else{ |
// trec=lstructlist; |
// while(trec->left!=NULL)trec=trec->left; |
// trec->left=newrec; |
// } |
// newrec->right=newrec->left=NULL; |
lrec=addlocalvar(itok.name,tk_structvar,paramsize); |
lrec->rec.newid=(char *)tteg; |
lrec->rec.flag=tteg->flag; |
lrec->rec.recrm=1; |
lrec->rec.recpost=LOCAL; |
goto endparam; |
} |
lrec=addlocalvar(itok.name,sparamtok,paramsize); |
lrec->rec.npointr=(unsigned short)numpointr; |
endparam: |
lrec->rec.type=tp_paramvar; |
lrec->rec.recsize=lsize; |
paramsize+=lsize; |
endparam1: |
nexttok(); |
}while(tok==tk_camma); |
} |
}while(tok==tk_semicolon); |
param[i]=0; |
// puts(param); |
} |
|
void CharToBackBuf(char c) |
{ |
if(SizeBackBuf==0){ |
MaxSizeBackBuf=STRLEN; |
BackTextBlock=(char *)MALLOC(STRLEN); |
} |
else if(SizeBackBuf==MaxSizeBackBuf){ |
MaxSizeBackBuf+=STRLEN; |
BackTextBlock=(char *)REALLOC(BackTextBlock,MaxSizeBackBuf); |
} |
BackTextBlock[SizeBackBuf++]=c; |
} |
|
void AddBackBuf(int oinptr,char ocha) |
//ñîçäàòü ëèñòèíã íà÷àëüíîé èíèöèàëèçàöèè ëîñàëüíûõ ïåðåìåííûõ |
{ |
int numblock=0; |
unsigned char save; |
char bcha; |
inptr=oinptr; |
cha=ocha; |
for(;;){ |
save=TRUE; |
switch(cha){ |
case '(': |
case '{': |
case '[': |
numblock++; |
break; |
case ')': |
case '}': |
case ']': |
numblock--; |
if(numblock<0)return; |
break; |
case ',': |
if(numblock>0)break; |
tok=tk_camma; |
goto endp; |
case ';': |
case 26: |
tok=tk_semicolon; |
endp: |
CharToBackBuf(';'); |
nextchar(); |
inptr2=inptr; |
cha2=cha; |
return; |
case '/': //îòñëåäèòü êîììåíòàðèè |
nextchar(); |
if(cha=='*'){ |
do{ |
nextchar(); |
if(cha=='*'){ |
nextchar(); |
if(cha=='/'){ |
save=FALSE; |
break; |
} |
} |
}while(cha!=26); |
} |
else if(cha=='/'){ |
do{ |
nextchar(); |
}while(cha!=13&&cha!=26); |
} |
else CharToBackBuf('/'); |
break; |
case '"': |
case '\'': |
bcha=cha; |
do{ |
CharToBackBuf(cha); |
nextchar(); |
if(cha=='\\'){ |
CharToBackBuf(cha); |
nextchar(); |
CharToBackBuf(cha); |
nextchar(); |
} |
}while(cha!=bcha); |
break; |
} |
if(save)CharToBackBuf(cha); |
nextchar(); |
} |
} |
|
void RunBackText() |
{ |
ITOK oitok,ostructadr; |
SINFO ostr; |
unsigned char *oldinput; |
unsigned int oldinptr,oldendinptr; |
unsigned char bcha; |
int otok,otok2; |
char *ostartline; |
char *ostring,*obufrm; |
COM_MOD *ocurmod; |
ostring=BackString((char *)string); |
oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå |
oldinptr=inptr2; |
ostructadr=structadr; |
bcha=cha2; |
oldendinptr=endinptr; |
otok=tok; |
otok2=tok2; |
oitok=itok; |
ostr=strinf; |
strinf.bufstr=NULL; |
obufrm=bufrm; |
bufrm=NULL; |
|
ocurmod=cur_mod; |
cur_mod=NULL; |
|
input=(unsigned char *)BackTextBlock; |
inptr2=1; |
cha2=input[0]; |
tok=tk_openbrace; |
SizeBackBuf=0; |
ostartline=startline; |
startline=(char*)input; |
endinptr=strlen((char *)input); |
endinput=startline+endinptr; |
|
doblock(); |
|
endoffile=0; |
startline=ostartline; |
strinf=ostr; |
free(input); |
input=oldinput; |
inptr2=oldinptr; |
cha2=bcha; |
endinptr=oldendinptr; |
tok=otok; |
itok=oitok; |
if(bufrm)free(bufrm); |
bufrm=obufrm; |
tok2=otok2; |
strcpy((char *)string,ostring); |
if(strinf.bufstr)free(strinf.bufstr); |
structadr=ostructadr; |
free(ostring); |
|
cur_mod=ocurmod; |
} |
|
int PushLocInit(int ofs) |
{ |
ITOK oitok,ostructadr,wtok; |
SINFO ostr; |
unsigned char *oldinput; |
unsigned int oldinptr,oldendinptr; |
unsigned char bcha; |
int otok,otok2; |
char *ostartline; |
char *ostring,*obufrm; |
int retcode=FALSE; |
// if(bufrm)puts(bufrm); |
ostring=BackString((char *)string); |
oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå |
oldinptr=inptr2; |
ostructadr=structadr; |
bcha=cha2; |
oldendinptr=endinptr; |
otok=tok; |
otok2=tok2; |
oitok=itok; |
ostr=strinf; |
strinf.bufstr=NULL; |
obufrm=bufrm; |
bufrm=NULL; |
input=(unsigned char *)BackTextBlock; |
inptr2=ofs; |
ostartline=startline; |
cha2=input[inptr2++]; |
endinptr=strlen((char *)input); |
startline=(char *)input+ofs; |
endinput=startline+endinptr; |
nexttok(); |
wtok=itok; |
nexttok(); |
nexttok(); |
if((retcode=Push(&wtok))!=FALSE){ |
retcode=TRUE; |
for(inptr2=ofs;;inptr2++){ |
cha2=input[inptr2]; |
input[inptr2]=' '; |
if(cha2==';'||cha2==0)break; |
} |
} |
endoffile=0; |
startline=ostartline; |
strinf=ostr; |
input=oldinput; |
inptr2=oldinptr; |
cha2=bcha; |
endinptr=oldendinptr; |
tok=otok; |
itok=oitok; |
if(bufrm)free(bufrm); |
bufrm=obufrm; |
tok2=otok2; |
strcpy((char *)string,ostring); |
if(strinf.bufstr)free(strinf.bufstr); |
structadr=ostructadr; |
free(ostring); |
return retcode; |
} |
|
int pushinit(int localline,unsigned int ofs) |
{ |
int oline=linenumber; |
COM_MOD *bcur_mod; |
int retcode; |
linenum2=localline; |
bcur_mod=cur_mod; |
cur_mod=NULL; |
retcode=PushLocInit(ofs); |
cur_mod=bcur_mod; |
linenumber=linenum2=oline; |
return retcode; |
} |
|
int PossiblePush() |
{ |
int retcode=FALSE; |
nexttok(); |
switch(tok){ |
case tk_dwordvar: |
case tk_longvar: |
case tk_reg32: |
if(am32==FALSE)break; |
case tk_postnumber: |
case tk_string: |
case tk_intvar: |
case tk_wordvar: |
case tk_reg: |
if(tok2==tk_semicolon||tok2==tk_camma)retcode=TRUE; |
break; |
case tk_undefofs: |
tok=tk_number; |
goto chnum; |
case tk_minus: |
if(tok2!=tk_number)break; |
nexttok(); |
case tk_number: |
chnum: |
doconstlongmath(); |
if(tok==tk_semicolon||tok==tk_camma)retcode=TRUE; |
break; |
} |
|
//// New 20.07.07 22:01 |
if(bufrm){ |
free(bufrm); |
bufrm=NULL; |
} |
if(strinf.bufstr){ |
free(strinf.bufstr); |
strinf.bufstr=NULL; |
} |
//////////////////////////// |
|
return retcode; |
} |
|
#define MAXLOCVAR 128 |
|
void declarelocals(int mode,int finline) /* declare locals */ |
/*-----------------01.06.02 15:12------------------- |
mode = 0 if local vars prior { |
mode = 1 if local vars after { |
--------------------------------------------------*/ |
{ |
unsigned int size,ssize,localtok; |
int binptr; |
int flag=0; |
char bcha; |
int slocaltok; |
int numpointr,type; |
unsigned int loop; |
static int localline; |
static int numinit; |
static int maxlocvar; |
static LILV *lilv=NULL; |
static int headerinit; |
if(localsize==0)localline=0; |
if(lilv==NULL){ |
numinit=0; |
lilv=(LILV *)MALLOC(sizeof(LILV)*MAXLOCVAR); |
maxlocvar=MAXLOCVAR; |
if(paramsize&&(!finline))headerinit=TRUE; |
else headerinit=FALSE; |
} |
dynamic_flag=0; |
do{ |
while(tok==tk_semicolon)nexttok(); |
if(tok==tk_static){ |
flag|=f_static; |
nexttok(); |
} |
size=0; |
switch(tok){ |
case tk_union: |
loop=dounion(0,flag); |
goto locstruct; |
case tk_struct: |
loop=LocalStruct(flag,&localline); |
locstruct: |
(lilv+numinit)->size=-loop; |
break; |
case tk_int: localtok=tk_intvar; size=2; break; |
case tk_word: localtok=tk_wordvar; size=2; break; |
case tk_char: localtok=tk_charvar; size=1; break; |
case tk_byte: localtok=tk_bytevar; size=1; break; |
case tk_long: localtok=tk_longvar; size=4; break; |
case tk_dword: localtok=tk_dwordvar; size=4; break; |
case tk_float: localtok=tk_floatvar; size=4; break; |
case tk_qword: localtok=tk_qwordvar; size=8; break; |
case tk_double: localtok=tk_doublevar; size=8; break; |
default: |
if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_pointer||tok==tk_proc |
||tok==tk_declare||tok==tk_undefproc||tok==tk_structvar|| |
(FindTeg(FALSE)==NULL&&FindTeg(TRUE)==NULL)){ |
if(mode==0){ |
(lilv+numinit)->size=0; |
datatype_expected(); |
nexttok(); |
} |
else{ |
if(localsize){ |
if(!finline){ |
numpointr=0; |
if(SizeBackBuf){ |
BackTextBlock[SizeBackBuf]=0; |
for(type=numinit-1,numpointr=0;type>=0;type--){//îïð ÷èñëî èíèö. ïåðåìåííûõ â êîíöå |
if((lilv+type)->size<=0)break; |
numpointr+=(lilv+type)->size; |
} |
type++; //÷èñëî îñòàâøèõñÿ ïåðåìåííûõ |
ssize=type; |
} |
size=localsize; |
if(lilv->size<=0&&optimizespeed==0&&chip>1){ |
size-=numpointr; |
if(headerinit)outptr-=3; /* remove PUSH BP and MOV BP,SP */ |
op(0xC8); /* ENTER */ |
outword(size); /* # of locals */ |
op(0x00); /* level = 0 */ |
flag=0; |
type=0; |
headerinit=TRUE; |
size=numpointr; |
} |
else{ |
if(headerinit==FALSE){ |
Enter(); |
headerinit=TRUE; |
} |
flag=1; |
} |
if(SizeBackBuf){ |
if(lilv->size>0){ //åñòü èíèö ïåðåìåííûå â íà÷àëå |
for(loop=0;loop<numinit;loop++){ |
// printf("size%d=%d %s\n",loop,(lilv+loop)->size,BackTextBlock); |
if((lilv+loop)->size<=0)break; |
if(pushinit(localline,(lilv+loop)->ofs)==FALSE)break; |
(lilv+loop)->rec->fuse|=INITVAR; |
size-=Align((lilv+loop)->size,(am32==FALSE?2:4)); |
type--; |
} |
} |
if(size){ |
binptr=size-numpointr; |
if(binptr){ |
if(!optimizespeed&&type<3&&(type*(am32+1)*2)>=binptr)for(;type!=0;type--)op(0x50+ECX); |
else{ |
if(binptr<128){ |
outword(0xEC83); |
op(binptr); |
} |
else{ |
outword(0xEC81); |
if(am32==FALSE)outword(binptr); |
else outdword((unsigned long)binptr); |
} |
} |
} |
if(numpointr){ |
for(;ssize<numinit;ssize++){ |
// printf("size%d=%d %s\n",loop,(lilv+loop)->size,BackTextBlock); |
if(pushinit(localline,(lilv+ssize)->ofs)==FALSE)break; |
(lilv+ssize)->rec->fuse|=INITVAR; |
} |
} |
} |
} |
else if(flag){ |
if(localsize<128){ |
outword(0xEC83); |
op(localsize); |
} |
else{ |
outword(0xEC81); |
if(am32==FALSE)outword(localsize); |
else outdword((unsigned long)localsize); |
} |
} |
} |
else{ //finline |
if(SizeBackBuf!=0){ |
free(BackTextBlock); |
SizeBackBuf=0; |
} |
} |
} |
if(psavereg->size){ |
if(psavereg->all){ |
op(0x60); |
addESP+=am32==FALSE?16:32; |
} |
else{ |
for(int i=0;i<8;i++){ |
if(psavereg->reg[i]){ |
op66(psavereg->reg[i]); |
op(0x50+i); |
addESP+=am32==FALSE?2:4; |
|
} |
} |
} |
if(ESPloc&&am32&&(itok.type==tp_localvar||itok.type==tp_paramvar))itok.number+=addESP; |
} |
// printf("numinit=%d firstinit=%d\n%s\n",numinit,firstinit,BackTextBlock); |
if(SizeBackBuf!=0){ |
CharToBackBuf('}'); |
CharToBackBuf(0); |
int oline=linenumber; |
linenum2=localline; |
COM_MOD *bcur_mod; |
bcur_mod=cur_mod; |
cur_mod=NULL; |
RunBackText(); |
cur_mod=bcur_mod; |
linenumber=linenum2=oline; |
} |
if(lilv){ |
free(lilv); |
lilv=NULL; |
} |
return; |
} |
} |
else{ |
loop=LocalStruct(flag,&localline); |
(lilv+numinit)->size=-loop; |
} |
break; |
} |
if(size!=0){ |
do{ |
binptr=inptr2; |
bcha=cha2; |
skipfind=TRUE; //çàïðåòèòü èñêàòü â ãëîáàëüíîì äåðåâå |
nexttok(); |
if(tok==tk_static){ |
flag|=f_static; |
binptr=inptr2; |
bcha=cha2; |
nexttok(); |
} |
slocaltok=localtok; |
ssize=size; |
numpointr=0; |
type=tp_localvar; |
while(tok==tk_mult){ |
binptr=inptr2; |
bcha=cha2; |
nexttok(); |
numpointr++; |
} |
if(tok!=tk_ID&&tok!=tk_id)idalreadydefined(); |
else{ |
long numcopyvar; |
numcopyvar=1; |
localrec *lrec=addlocalvar(itok.name,slocaltok,(flag&f_static)==0?localsize:postsize); |
loop=ssize; |
if(numpointr)loop=am32==TRUE?4:2; |
skipfind=FALSE; //ðàçðåøèòü ïîèñê â ãëîáàëüíîì äåðåâå |
if(tok2==tk_openblock){//[ |
nexttok(); |
nexttok(); |
CheckMinusNum(); |
if(tok!=tk_number){ |
numexpected(); |
nexttok(); |
} |
else numcopyvar=doconstlongmath(); |
loop=numcopyvar*ssize; |
if(tok!=tk_closeblock)expected(']'); |
} |
lrec->rec.recsize=loop; |
if(!mode){ |
nexttok(); |
} |
if(flag&f_static){ |
if(tok==tk_assign||(mode&&tok2==tk_assign)){ |
if(mode)nexttok(); |
if(numpointr){ |
type=tk_char+slocaltok-tk_charvar; |
slocaltok=tk_pointer; |
} |
lrec->rec.rectok=slocaltok; |
lrec->rec.recnumber=0; |
lrec->rec.recpost=DYNAMIC_VAR; |
lrec->rec.line=linenumber; |
lrec->rec.file=currentfileinfo; |
lrec->rec.count=0; |
// lptr->rec.type=(unsigned short)type; |
lrec->rec.npointr=(unsigned short)numpointr; |
lrec->rec.sbuf=dynamic_var(); |
lrec->rec.recsib=type; |
lrec->rec.type=tp_gvar; |
|
// if(strcmp(lrec->rec.recid,"nnil")==0)crec=&lrec->rec; |
|
} |
else{ |
lrec->rec.type=tp_postvar; |
AddPostData(loop); |
if(mode)nexttok(); |
} |
} |
else{ |
lrec->rec.type=tp_localvar; |
lrec->rec.npointr=(unsigned short)numpointr; |
localsize+=loop; |
if(mode)nexttok(); |
(lilv+numinit)->size=-loop; |
if(tok==tk_assign){ |
if(localline==0)localline=linenumber; |
if(numcopyvar!=1){ |
int i=binptr; |
while(input[i]!='[')i++; |
i++; |
input[i]='0'; |
i++; |
for ( int j=1;j!=0;i++){ |
switch(input[i]){ |
case '[': |
j++; |
break; |
case ']': |
j--; |
break; |
} |
if(j!=0)input[i]= ' '; |
} |
} |
else{ |
switch(slocaltok){ |
case tk_floatvar: |
case tk_doublevar: |
case tk_qwordvar: |
// (lilv+numinit)->ofs=-1; |
break; |
default: |
if(PossiblePush()){ |
(lilv+numinit)->size=loop; |
(lilv+numinit)->rec=lrec; |
} |
break; |
} |
} |
(lilv+numinit)->ofs=SizeBackBuf; |
AddBackBuf(binptr,bcha); |
// if(bufrm)puts(bufrm); |
} |
numinit++; |
if(numinit==maxlocvar){ |
maxlocvar+=MAXLOCVAR; |
lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV)); |
} |
lrec->rec.recnumber=-lrec->rec.recnumber-Align(loop,(am32==FALSE?2:4)); |
} |
} |
if(localsize)localsize=Align(localsize,(am32==FALSE?2:4)); |
}while(tok==tk_camma); |
seminext(); |
} |
else{ |
numinit++; |
if(numinit==maxlocvar){ |
maxlocvar+=MAXLOCVAR; |
lilv=(LILV *)REALLOC(lilv,maxlocvar*sizeof(LILV)); |
} |
} |
flag=0; |
// printf("tok=%d %s\n",tok,BackTextBlock); |
}while(tok!=tk_openbrace&&tok!=tk_eof); |
} |
|
int CheckDeclareProc() |
{ |
unsigned int i=inptr2-1; |
while(input[i]!='('){ |
i++; |
if(i>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
lab1: |
i++; |
for(int j=1;j!=0;i++){ |
char c=input[i]; |
if(c=='(')j++; |
else if(c==')')j--; |
if(i>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
for(;;i++){ |
if(input[i]=='(')goto lab1; |
if(input[i]>' ')break; |
if(i>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
|
for(;;i++){ |
if(input[i]==';'||input[i]==',')return TRUE; //îáúÿâëåíèå ïðîöåäóðû |
if(input[i]>' ')break; |
if(i>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
return FALSE; |
} |
|
void IsUses(idrec *rec) |
{ |
int i; |
if(tok==tk_openbracket&&stricmp(itok2.name,"uses")==0){ |
nexttok(); |
i=0; |
nexttok(); |
while(tok==tk_reg32||tok==tk_reg||tok==tk_beg){ |
if(tok==tk_beg&&itok.number>3)itok.number-=4; |
i=i|(1<<itok.number); |
nexttok(); |
if(tok==tk_camma)nexttok(); |
} |
if(strcmp(itok.name,"allregs")==0){ |
i=256; |
nexttok(); |
} |
rec->recpost=0xFF^i; |
expecting(tk_closebracket); |
} |
} |
|
void declare_procedure(int oflag,int orm,int npointr) |
{ |
int i,next=TRUE,j; |
char pname[IDLENGTH]; |
idrec *rec; |
strcpy(pname,itok.name); |
param[0]=0; |
nexttok(); |
if(npointr)expecting(tk_closebracket); |
expecting(tk_openbracket); |
if((oflag&f_typeproc)==tp_fastcall)declareparamreg(); |
else declareparamstack(); |
if(tok2==tk_assign)nexttok(); |
itok.post=1; |
if(npointr){ |
itok.segm=DS; |
itok.type=tk_proc; |
itok.sib=am32==FALSE?rm_d16:rm_d32; |
i=2; |
if(am32||(oflag&f_far))i=4; |
if(tok==tk_assign||(notpost==TRUE&&dynamic_flag==0)){ //= èíèöèàëèçèðîâàíàÿ ïåðåìåííàÿ |
if((oflag&f_extern))preerror("extern variable do not initialize at declare"); |
if(alignword&&(!dynamic_flag))alignersize+=AlignCD(DS,i); |
FindOff((unsigned char *)pname,DS); |
itok.number=outptrdata; |
if(tok!=tk_assign){ |
if(dbg&2)AddDataLine(i); |
outword(0); |
if(i==4)outword(0); |
} |
else{ |
ITOK oitok; |
oitok=itok; |
initglobalvar(tk_word,1,i,variable); |
itok=oitok; |
next=FALSE; |
} |
itok.post=0; |
datasize+=i; |
} |
else{ |
if((oflag&f_extern)==0){ |
itok.number=postsize; |
AddPostData(i); |
} |
else itok.number=externnum++; |
} |
j=tok; |
tok=tk_pointer; |
} |
else{ |
tok=tk_declare; |
itok.type=tp_declare; |
itok.number=(oflag&f_extern)!=0?externnum++:secondcallnum++; |
itok.segm=NOT_DYNAMIC; |
itok.post=0; |
} |
itok.npointr=(unsigned short)npointr; |
itok.rm=orm; |
itok.flag=oflag; |
if(itok.rm==tokens)itok.rm=(am32==0?tk_word:tk_dword); |
// printf("rm=%d %s\n",itok.rm,itok.name); |
strcpy((char *)string,param); |
rec=addtotree(pname); |
if(next)nexttok(); |
else tok=j; |
IsUses(rec); |
} |
|
void define_procedure() |
{ |
if(dynamic_flag)dynamic_proc(); |
else{ |
itok.segm=NOT_DYNAMIC; |
if(AlignProc!=FALSE)AlignCD(CS,alignproc); |
procedure_start=outptr; |
if(dbg)AddLine(); |
// itok.flag&=~f_static; 26.08.05 00:09 |
setproc((tok==tk_id||tok==tk_ID)?0:1); |
dopoststrings(); |
} |
} |
|
void interruptproc() |
{ |
char *bstring; |
ITOK otok; |
inlineflag=0; |
procedure_start=outptr; |
returntype=tk_void; |
current_proc_type=f_interrupt; |
localsize=paramsize=0; |
nexttok(); |
// FindOff((unsigned char *)itok.name,CS); |
itok.number=outptr; |
itok.segm=NOT_DYNAMIC; |
itok.post=0; |
itok.rm=tk_void; |
itok.flag=0; |
if(tok==tk_ID||tok==tk_id){ |
tok=tk_interruptproc; |
itok.type=tp_ucnovn; |
addtotree((char *)string); |
} |
else if(tok==tk_undefproc){ |
tok=tk_interruptproc; |
long hold=updatetree(); |
updatecall((unsigned int)hold,(unsigned int)outptr,0); |
} |
else idalreadydefined(); |
itok.rec->count=FindOff((unsigned char *)itok.name,CS); |
bstring=BackString((char *)string); |
otok=itok; |
nextexpecting2(tk_openbracket); |
expecting(tk_closebracket); |
if(tok==tk_inline){ |
inlineflag=1; |
nexttok(); |
} |
else if(tok!=tk_openbrace)declarelocals(0); |
expecting(tk_openbrace); |
declarelocals(1); |
startblock(); |
doblock2(); /* do proc */ |
endblock(); |
if(retproc==FALSE){ |
if(inlineflag==0)leaveproc(); |
else if(localsize>0)Leave(); |
} |
initBP=0; |
strcpy((char *)string,bstring); |
itok=otok; |
tok=tk_interruptproc; |
itok.size=outptr-procedure_start; |
updatetree(); |
free(bstring); |
killlocals(); |
nexttok(); |
dopoststrings(); |
} |
|
int skipstring(int pos,unsigned char term) |
{ |
unsigned char c; |
do{ |
pos++; |
c=input[pos]; |
if(c==0x5C){ |
pos++; |
continue; |
// c=input[pos+1]; |
} |
}while(c!=term); |
return pos; |
} |
|
int skipcomment(int pos) |
{ |
if(input[pos+1]=='*'){ |
pos+=2; |
for(;;pos++){ |
if(input[pos]==13){ |
linenumber++; |
} |
else if(input[pos]=='*'){ |
pos++; |
if(input[pos]=='/')break; |
} |
if((unsigned int)pos>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
} |
else if(input[pos+1]=='/'){ |
pos+=2; |
for(;;pos++){ |
if(input[pos]==13){ |
linenumber++; |
break; |
} |
if(input[pos]==10)break; |
} |
} |
return pos; |
} |
|
int swapparam() |
{ |
int i,ns,j,lastofs; |
int linep,linebak; |
char c,ochar; |
unsigned char *bufpar; |
int numpar=0; |
unsigned char *oldinput; |
paraminfo *pi; |
if(tok!=tk_openbracket){ |
expected('('); |
do{ |
nexttok(); |
}while(tok2!=tk_semicolon&&tok!=tk_eof); |
return 0; |
} |
pi=(paraminfo *)MALLOC(128*sizeof(paraminfo)); |
do{ |
inptr2--; |
}while(input[inptr2]!='('); |
inptr2++; |
pi->ofspar=inptr2; |
pi->type[0]=0; |
linep=linenumber; |
for(i=inptr2,ns=1;ns>0;i++){ //ïîèñê êîíöà ïàðàìåòðîâ |
switch(input[i]){ |
case '(': ns++; break; |
case ')': ns--; break; |
case ',': |
if(ns==1){ |
if(numpar==127)preerror("To many parametrs in function"); |
numpar++; |
(pi+numpar)->ofspar=i+1; |
(pi+numpar)->type[0]=0; |
} |
break; |
case '/': |
i=skipcomment(i); |
break; |
case '"': |
case 0x27: |
i=skipstring(i,input[i]); |
break; |
case 13: |
linenumber++; |
break; |
} |
if((unsigned int)i>=endinptr){ |
unexpectedeof(); |
break; |
} |
} |
for(j=0,ns=0;param[j]!=0;j++,ns++){//ïåðåâåðíóòü çàäåêëàðèðóåìûå ïàðàìåòðû |
lastofs=0; |
ochar=c=param[j]; |
(pi+ns)->type[0]=c; |
while(c=='*'){ |
j++; |
ochar=c=param[j]; |
(pi+ns)->type[++lastofs]=c; |
} |
if(c=='A'){ |
if(ns){ |
while(ns<=numpar){ |
(pi+ns)->type[0]='U'; |
(pi+ns)->type[1]=0; |
ns++; |
} |
break; |
} |
} |
if(ochar=='T'){ |
do{ |
j++; |
lastofs++; |
c=param[j]; |
(pi+ns)->type[lastofs]=c; |
}while(isdigit(c)); |
(pi+ns)->type[lastofs]=0; |
j--; |
continue; |
} |
c=param[j+1]; |
if(c>='0'&&c<='7'){ |
(pi+ns)->type[1]=c; |
j++; |
lastofs++; |
if(ochar=='Q'){ |
(pi+ns)->type[2]=param[j+1]; |
j++; |
lastofs++; |
} |
} |
(pi+ns)->type[++lastofs]=0; |
} |
ns--; |
for(j=0;ns>=0;ns--){ |
lastofs=0; |
c=(pi+ns)->type[lastofs++]; |
while(c!=0){ |
param[j++]=c; |
c=(pi+ns)->type[lastofs++]; |
} |
} |
param[j]=0; |
// puts(param); |
// if(crec)printf("start0 swapparams num=%08X\n",crec->recnumber); |
bufpar=(unsigned char *)MALLOC(i-inptr2+2); |
// printf("crec=%08X size=%d bufpar=%08X size=%d\n",crec,sizeof(idrec),bufpar,i-inptr2+2); |
inptr2=i; |
ochar=input[inptr2]; |
inptr2++; |
i--; |
lastofs=0; |
for(;;){ |
j=(pi+numpar)->ofspar;//[numpar]; |
for(ns=0;(j+ns)!=i;ns++){ |
bufpar[lastofs++]=input[j+ns]; |
} |
i=j-1; |
numpar--; |
if(numpar<0)break; |
bufpar[lastofs++]=','; |
} |
bufpar[lastofs++]=')'; |
*(short *)&bufpar[lastofs++]=';'; |
free(pi); |
oldinput=input; //ñîõð íåêîòîð ïåðåìåíûå |
// puts((char *)(input+inptr)); |
// printf("cur_mod=%08X input=%08X\n",cur_mod,input); |
ns=inptr2; |
j=endinptr; |
input=bufpar; |
// puts((char *)bufpar); |
inptr2=1; |
cha2=input[0]; |
endinptr=lastofs; |
tok=tk_openbracket; |
if(bufrm!=NULL){ |
free(bufrm); |
bufrm=NULL; |
} |
if(strinf.bufstr!=NULL){ |
free(strinf.bufstr); |
strinf.bufstr=NULL; |
} |
linebak=linenumber; |
linenumber=linep; |
i=doparams(); |
endoffile=0; |
input=oldinput; |
inptr2=ns; |
cha2=ochar; |
endinptr=j; |
linenumber=linebak; |
// printf("cur_mod=%08X input=%08X\n",cur_mod,input); |
free(bufpar); |
// puts((char *)input); |
return i; |
} |
|
int getrazr(int type) |
{ |
switch(type){ |
case tk_char: |
case tk_byte: |
return r8; |
case tk_word: |
case tk_int: |
return r16; |
case tk_long: |
case tk_dword: |
case tk_float: |
return r32; |
case tk_qword: |
case tk_double: |
return r64; |
} |
if(am32)return r32; |
return r16; |
} |
|
int doparams() /* do stack procedure parameter pushing */ |
{ |
char done=0,next; |
int vartype; |
int stackpar=0; |
int i; |
int jj=0; |
char *bparam; //áóôåð äëÿ äåêëàðèðóåìûõ ïàðàìåòðîâ |
int ip=-1; //íîìåð ïàðàìåòðà |
char *ofsstr=NULL; |
int useAX=FALSE; |
int retreg=AX; |
unsigned char oaddstack=addstack; |
unsigned char oinline=useinline; |
useinline=0; |
int structsize; |
struct idrec *ptrs; |
addstack=FALSE; |
if(am32!=FALSE)jj=2; |
bparam=BackString(param); |
if(param[0]!=0)ip=0; |
ofsstr=GetLecsem(tk_camma,tk_closebracket); |
expectingoperand(tk_openbracket); |
ClearRegister(); |
if(tok!=tk_closebracket){ |
while(tok!=tk_eof&&done==0){ |
useAX=FALSE; |
retreg=AX; |
i=0; |
next=1; |
if(ip!=-1){ |
if(bparam[ip]=='*'){ |
while(bparam[ip]=='*')ip++; |
ip++; |
vartype=(am32==FALSE?tk_word:tk_dword); |
} |
else{ |
if((vartype=GetTypeParam(bparam[ip++]))==0)ip=-1; |
else{ |
int c=bparam[ip]; |
if(vartype==tk_struct){ |
structsize=0; |
while(isdigit(c)){ |
c-='0'; |
structsize=structsize*10+c; |
ip++; |
c=param[ip]; |
} |
} |
else if(c>='0'&&c<='7'){ |
ip++; |
c-=0x30; |
if(vartype==tk_fpust)float2stack(c); |
else{ |
if(vartype==tk_qword){ |
c|=(bparam[ip]-0x30)*256; |
ip++; |
} |
CalcRegPar(c,vartype,&ofsstr); |
} |
goto endparam; |
} |
} |
} |
if(vartype==tk_multipoint){ |
vartype=tokens; |
ip--; |
} |
} |
if(tok==tk_string){ |
if(chip<2||(optimizespeed&&(chip==5||chip==6))){ |
op(0xB8); |
if(am32!=FALSE)outdword(addpoststring()); |
else outword(addpoststring()); // MOV AX,imm16 |
op(0x50); |
useAX=TRUE; |
ClearReg(EAX); //íàäî äîáàâèòü îïòèìèçàöèþ ðåãèñòðîâ à ïîêà òàê |
} /* PUSH AX */ |
else{ |
op(0x68); /* PUSH imm16 */ |
if(am32!=FALSE)outdword(addpoststring()); |
else outword(addpoststring()); |
if(cpu<2)cpu=2; |
} |
stackpar+=2+jj; |
addESP+=2+jj; |
nexttok(); |
} |
else{ |
if(tok>=tk_char&&tok<=tk_double){ |
vartype=tok; |
getoperand(); |
} |
else if(tok==tk_openbracket){ |
nexttok(); |
if(tok>=tk_char&&tok<=tk_double)vartype=tok; |
nexttok(); |
expectingoperand(tk_closebracket); |
} |
else{ |
if(ip==-1||vartype==tokens){ |
switch(tok){ |
case tk_longvar: vartype=tk_long; break; |
case tk_floatvar: vartype=tk_float; break; |
case tk_dwordvar: vartype=tk_dword; break; |
case tk_doublevar: vartype=tk_double; break; |
case tk_qwordvar: vartype=tk_qword; break; |
case tk_number: |
vartype=(itok.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword)); |
break; |
case tk_reg32: vartype=tk_dword; break; |
case tk_reg64: vartype=tk_qword; break; |
case tk_minus: |
if(tok2==tk_number){ |
vartype=itok2.rm==tk_float?tk_float:(am32==FALSE?tk_word:tk_dword); |
break; |
} |
default: vartype=(am32==FALSE?tk_word:tk_dword); break; |
} |
} |
} |
if(tok==tk_minus&&tok2==tk_number&&vartype!=tk_float){ //ïðîâåðêà îòðèöàòåëüíîãî ÷èñëà |
nexttok(); |
itok.lnumber=-itok.lnumber; |
} |
int razr; |
if(ofsstr){ |
razr=getrazr(vartype); |
int retr; |
if((retr=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ |
// printf("reg=%d\n",retr); |
GetEndLex(tk_camma,tk_closebracket); |
if(razr==r8)razr=am32==0?r16:r32; |
if(retr==SKIPREG)retreg=AX; |
else retreg=retr; |
op66(razr); |
op(0x50+retreg); |
useAX=TRUE; |
stackpar+=razr; |
addESP+=razr; |
goto endparam1; |
} |
// printf("reg=%d\n",retr); |
} |
razr=r32; |
if(itok2.type==tp_opperand||tok==tk_minus){ //ñîñòàâíîå |
switch(vartype){ |
case tk_struct: |
i=structsize/((am32+1)*2); |
do_e_axmath(0,r32,&ofsstr); |
ClearReg(AX); |
if(am32){ |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=4; |
outword(0x70FF); |
op(itok.number); |
} |
outword(0x30FF); |
} |
else{ |
ClearReg(BX); |
warningreg(regs[1][BX]); |
outword(0xC389); |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=2; |
outword(0x77FF); |
op(itok.number); |
} |
outword(0x37FF); |
} |
stackpar+=structsize; |
addESP+=structsize; |
break; |
case tk_char: i=1; |
case tk_byte: |
stackpar+=jj; |
doalmath((char)i,&ofsstr); |
addESP+=2+jj; |
break; |
case tk_int: i=1; |
case tk_word: |
if(am32==FALSE)razr=r16; |
stackpar+=jj; |
goto blokl; |
case tk_long: i=1; |
case tk_dword: |
if(cpu<3)cpu=3; |
stackpar+=2; |
blokl: |
if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))&&(tok==tk_number |
||tok==tk_undefofs||tok==tk_postnumber)){ |
int otok=tok; |
ITOK oitok=itok; |
tok=tk_number; |
if(OnlyNumber(i)){ |
op66(razr); |
if(otok==tk_number&&(postnumflag&f_reloc)==0&&short_ok(itok.number,razr==r16?FALSE:TRUE)!=0){ |
op(0x6A); // PUSH 8 extend to 32 bit |
op((unsigned int)itok.number); |
} |
else{ |
op(0x68); // PUSH const |
if(otok==tk_undefofs)AddUndefOff(0,oitok.name); |
else if(otok==tk_postnumber)(oitok.flag&f_extern)==0?setwordpost(&oitok):setwordext(&oitok.number); |
else if((postnumflag&f_reloc)!=0)AddReloc(); |
if(razr==r16)outword(itok.number); |
else outdword(itok.number); |
} |
addESP+=razr==r16?2:4; |
goto nopush; |
} |
tok=otok; |
} |
do_e_axmath(i,razr,&ofsstr); |
addESP+=razr==r16?2:4; |
op66(razr); |
break; |
case tk_double: |
if(doeaxfloatmath(tk_stackstart,0,4)!=tk_stackstart){ |
op66(r32); |
op(0x50+EDX); // PUSH EDX |
op66(r32); |
op(0x50); //push eax |
useAX=TRUE; |
} |
if(cpu<3)cpu=3; |
stackpar+=6; |
addESP+=8; |
goto nopush; |
case tk_float: |
if(doeaxfloatmath(tk_stackstart)!=tk_stackstart){ |
op66(r32); |
if(!am32){ |
op(0x89); // mov ssdword[bp+2]=eax |
op(0x46); |
op(2); |
Leave(); |
} |
else{ |
op(0x50); //push eax |
useAX=TRUE; |
} |
} |
if(cpu<3)cpu=3; |
stackpar+=2; |
addESP+=4; |
goto nopush; |
case tk_qwordvar: |
i=EAX|(EDX*256); |
getintoreg64(i); |
doregmath64(i); |
op66(r32); |
op(0x50+EDX); // PUSH EDX |
op66(r32); |
next=0; |
if(cpu<3)cpu=3; |
stackpar+=6; |
addESP+=8; |
break; |
default: goto deflt; |
} |
op(0x50);/* PUSH AX or EAX */ |
useAX=TRUE; |
nopush: |
stackpar+=2; |
} |
else{ //îäèíî÷íîå |
// next=1; |
// printf("vartype=%d\n",vartype); |
if(vartype==tk_struct){ |
// printf("tok=%d %s\n",tok,itok.name); |
i=structsize/((am32+1)*2); |
switch(tok){ |
case tk_structvar: |
ptrs=itok.rec; |
if(ptrs->recpost==LOCAL){ |
if(ESPloc&&am32){ |
itok.rm=rm_mod10|rm_sib; |
itok.sib=0x24; |
itok.number+=addESP; |
} |
else{ |
itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); |
} |
itok.segm=SS; |
itok.post=0; |
compressoffset(&itok); |
} |
else{ |
itok.segm=DS; |
itok.rm=(am32==FALSE?rm_d16:rm_d32); //óñòàíîâêè ïî óìîë÷àíèþ |
itok.post=ptrs->recpost; |
if(i>1&&am32){ |
outseg(&itok,1); |
op(0xB8); |
outaddress(&itok); |
ClearReg(AX); |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=4; |
outword(0x70FF); |
op(itok.number); |
} |
outword(0x30FF); |
break; |
} |
} |
itok.sib=(am32==FALSE?CODE16:CODE32); |
itok.flag=ptrs->flag; |
itok.number+=structsize; |
for(;i>0;i--){ |
itok.number-=(am32+1)*2; |
outseg(&itok,2); |
op(0xFF); // PUSH [dword] |
op(0x30+itok.rm); |
outaddress(&itok); |
} |
break; |
case tk_rmnumber: |
itok.number+=structsize; |
for(;i>0;i--){ |
itok.number-=(am32+1)*2; |
outseg(&itok,2); |
op(0xFF); // PUSH [dword] |
op(0x30+itok.rm); |
outaddress(&itok); |
} |
break; |
case tk_undefofs: |
itok.rm=(am32==FALSE?rm_d16:rm_d32); //óñòàíîâêè ïî óìîë÷àíèþ |
case tk_postnumber: |
if(i>1&&am32){ |
if(tok!=tk_undefofs)outseg(&itok,1); |
op(0xB8); |
if(tok==tk_undefofs){ |
AddUndefOff(0,(char *)string); |
outdword(itok.number); |
} |
else outaddress(&itok); |
ClearReg(AX); |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=4; |
outword(0x70FF); |
op(itok.number); |
} |
outword(0x30FF); |
break; |
} |
itok.number+=structsize; |
for(;i>0;i--){ |
itok.number-=(am32+1)*2; |
if(tok!=tk_undefofs)outseg(&itok,2); |
op(0xFF); // PUSH [dword] |
op(0x30+itok.rm); |
if(tok==tk_undefofs){ |
AddUndefOff(0,(char *)string); |
outdword(itok.number); |
} |
else outaddress(&itok); |
} |
break; |
case tk_reg32: |
i--; |
itok.rm=structsize; |
for(;i>0;i--){ |
itok.rm-=4; |
op(0xFF); |
op(0x70+itok.number); |
op(itok.rm); |
} |
op(0xFF); |
op(0x30+itok.number); |
break; |
default: |
// preerror("for parametr function required structure"); |
do_e_axmath(0,r32,&ofsstr); |
ClearReg(AX); |
if(am32){ |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=4; |
outword(0x70FF); |
op(itok.number); |
} |
outword(0x30FF); |
} |
else{ |
ClearReg(BX); |
warningreg(regs[1][BX]); |
outword(0xC389); |
i--; |
itok.number=structsize; |
for(;i>0;i--){ |
itok.number-=2; |
outword(0x77FF); |
op(itok.number); |
} |
outword(0x37FF); |
} |
break; |
} |
stackpar+=structsize; |
addESP+=structsize; |
} |
else if(vartype<tk_long){ |
#ifdef OPTVARCONST |
CheckConstVar3(&tok,&itok,razr); |
#endif |
switch(tok){ |
case tk_reg: |
op(0x50+(unsigned int)itok.number); |
break; |
case tk_beg: |
if(vartype==tk_int||vartype==tk_word)goto deflt; |
if(itok.number<AH){ |
op(0x50+(unsigned int)itok.number); |
break; |
} |
op(0x88); |
op(0xC0+(unsigned int)itok.number*8); |
op(0x50); |
useAX=TRUE; |
break; |
case tk_seg: |
if(am32)goto deflt; |
if((unsigned int)itok.number<FS)op(0x06+(unsigned int)itok.number*8); |
else{ |
op(0xF); op(0x80+(unsigned int)itok.number*8); |
if((unsigned int)itok.number<=GS)if(cpu<3)cpu=3; |
} |
break; |
case tk_longvar: |
case tk_dwordvar: |
// if(am32==FALSE)goto deflt; |
i=2; |
case tk_intvar: |
case tk_wordvar: |
i+=2; |
CheckAllMassiv(bufrm,i,&strinf); |
outseg(&itok,2); |
op(0xFF); /* PUSH [word] */ |
op(0x30+itok.rm); |
outaddress(&itok); |
break; |
case tk_number: |
if(chip>=2/*&&(!(optimizespeed&&(chip==5||chip==6)))*/){ //28.03.07 19:04 |
if((itok.flag&f_reloc)==0&&short_ok(itok.number)){ |
op(0x6A); /* PUSH const */ |
op((unsigned int)itok.number); |
} |
else{ |
op(0x68); /* PUSH const */ |
if((itok.flag&f_reloc)!=0)AddReloc(); |
if(am32==FALSE)outword((unsigned int)itok.number); |
else outdword(itok.number); |
} |
if(cpu<2)cpu=2; |
} |
else{ |
MovRegNum(r16,itok.flag&f_reloc,itok.number,EAX); |
op(0x50); |
} |
break; |
case tk_apioffset: |
op(0x68); // PUSH const |
AddApiToPost(itok.number); |
break; |
case tk_postnumber: |
case tk_undefofs: |
if(chip>=2&&(!(optimizespeed&&(chip==5||chip==6)))){ |
op(0x68); // PUSH const |
if(tok==tk_undefofs)AddUndefOff(0,(char *)string); |
else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
if(am32==FALSE)outword((unsigned int)itok.number); |
else outdword(itok.number); |
break; |
} |
default: |
deflt: |
//if(tok==tk_new)puts("monovar default"); |
switch(vartype){ |
case tk_int: i=1; |
case tk_word: do_e_axmath(i,r16,&ofsstr); break; |
case tk_char: i=1; |
case tk_byte: doalmath((char)i,&ofsstr); break; |
default: beep(); break; |
} |
op(0x50); /* PUSH AX */ |
useAX=TRUE; |
next=0; |
break; |
} |
stackpar+=2+jj; |
addESP+=2+jj; |
} |
else if(vartype<tk_qword){ |
#ifdef OPTVARCONST |
CheckConstVar3(&tok,&itok,razr); |
#endif |
// printf("tok=%d %s\n",tok,itok.name); |
switch(tok){ // long or dword or float |
case tk_reg32: |
op66(r32); |
op(0x50+(unsigned int)itok.number); |
break; |
case tk_floatvar: |
if(vartype==tk_float)goto pushmem; |
case tk_qwordvar: |
case tk_dwordvar: |
case tk_longvar: |
if(optimizespeed&&(chip==5||chip==6))goto def; |
pushmem: |
CheckAllMassiv(bufrm,4,&strinf); |
op66(r32); |
outseg(&itok,2); |
op(0xFF); // PUSH [dword] |
op(0x30+itok.rm); |
// printf("push rm=%08X sib=%08X post=%u num=%08X rec=%08X flag=%08X %s\n",itok.rm,itok.sib,itok.post,itok.number,itok.rec,itok.flag,itok.name); |
outaddress(&itok); |
break; |
case tk_number: |
if(optimizespeed&&(chip==5||chip==6))goto def; |
if(vartype==tk_float){ |
itok.number=doconstfloatmath(); |
next=0; |
} |
else if(itok.rm==tk_double)itok.fnumber=itok.dnumber; |
op66(r32); |
if((itok.flag&f_reloc)==0&&short_ok(itok.number,TRUE)!=0){ |
op(0x6A); // PUSH 8 extend to 32 bit |
op((unsigned int)itok.number); |
} |
else{ |
op(0x68); // PUSH const |
if((itok.flag&f_reloc)!=0)AddReloc(); |
outdword(itok.number); |
} |
break; |
case tk_apioffset: |
op66(r32); |
op(0x68); // PUSH const |
AddApiToPost(itok.number); |
break; |
case tk_postnumber: |
case tk_undefofs: |
if(optimizespeed&&(chip==5||chip==6))goto def; |
op66(r32); |
op(0x68); // PUSH const |
if(tok==tk_undefofs)AddUndefOff(0,(char *)string); |
else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
outdword(itok.number); |
break; |
default: |
def: |
if(vartype==tk_float)doeaxfloatmath(tk_stackstart); |
else{ |
if(vartype==tk_long)i=1; |
// printf("tok=%d rm=%08X %s\n",tok,itok.rm,itok.name); |
if(tok==tk_rmnumber&&am32&&bufrm==NULL&&strinf.bufstr==NULL&& |
((itok.rm&7)!=4)&&((itok.rm&7)!=5)&& |
((itok.rm&rm_mod11)==rm_mod00)&&itok.number==0){ |
op66(r32); |
op(0x50+(itok.rm&7)); // PUSH rm reg |
break; |
|
} |
do_e_axmath(i,r32,&ofsstr); |
op66(r32); |
op(0x50); // PUSH EAX |
useAX=TRUE; |
} |
next=0; |
break; |
} |
stackpar+=4; |
addESP+=4; |
if(cpu<3)cpu=3; |
} |
else{ //qword or double |
#ifdef OPTVARCONST |
CheckConstVar3(&tok,&itok,razr); |
#endif |
switch(tok){ |
case tk_reg64: |
op66(r32); |
op(0x50+(unsigned int)itok.number/256); |
op66(r32); |
op(0x50+(unsigned int)itok.number&255); |
break; |
case tk_doublevar: |
case tk_qwordvar: |
itok.number+=4; |
compressoffset(&itok); |
CheckAllMassiv(bufrm,8,&strinf); |
for(i=0;i<2;i++){ |
op66(r32); |
outseg(&itok,2); |
op(0xFF); // PUSH [dword] |
op(0x30+itok.rm); |
outaddress(&itok); |
if(i==1)break; |
itok.number-=4; |
compressoffset(&itok); |
} |
break; |
case tk_reg32: |
op66(r32); |
outword(0x6A); // PUSH 8 extend to 32 bit |
op66(r32); |
op(0x50+(unsigned int)itok.number); |
break; |
case tk_number: |
long long lnumber; |
lnumber=itok.lnumber; |
itok.lnumber=lnumber>>32; |
for(i=0;i<2;i++){ |
op66(r32); |
if((i==0||(itok.flag&f_reloc)==0)&&short_ok(itok.number,TRUE)!=0){ |
op(0x6A); // PUSH 8 extend to 32 bit |
op((unsigned int)itok.number); |
} |
else{ |
op(0x68); // PUSH const |
if(i==1&&(itok.flag&f_reloc)!=0)AddReloc(); |
outdword(itok.number); |
} |
if(i==1)break; |
itok.number=lnumber; |
} |
break; |
case tk_postnumber: |
case tk_undefofs: |
op66(r32); |
outword(0x6A); // PUSH 8 extend to 32 bit |
op66(r32); |
op(0x68); // PUSH const |
if(tok==tk_undefofs)AddUndefOff(0,(char *)string); |
else (itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number); |
outdword(itok.number); |
break; |
default: |
if(vartype==tk_double)doeaxfloatmath(tk_stackstart,0,4); |
else{ |
op66(r32); |
outword(0x6A); |
do_e_axmath(0,r32,&ofsstr); |
op66(r32); |
op(0x50); // PUSH EAX |
useAX=TRUE; |
} |
next=0; |
break; |
} |
stackpar+=8; |
addESP+=8; |
if(cpu<3)cpu=3; |
} |
endparam1: |
if(next)nexttok(); |
|
} |
} |
endparam: |
if(ofsstr){ |
if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype)); |
free(ofsstr); |
ofsstr=NULL; |
} |
if(tok==tk_camma){ |
ofsstr=GetLecsem(tk_camma,tk_closebracket); |
getoperand(); |
} |
else if(tok==tk_closebracket)done=1; |
else{ |
expected(')'); |
done=1; |
} |
} |
} |
if(ofsstr){ |
if(useAX)IDZToReg(ofsstr,retreg,getrazr(vartype)); |
free(ofsstr); |
} |
if(ip!=-1&&bparam[ip]!=0&&bparam[ip]!='A'&&bparam[ip]!='V')missingpar(); |
free(bparam); |
setzeroflag=FALSE; |
addstack=oaddstack; |
useinline=oinline; |
return stackpar; |
} |
|
void CheckDir() |
{ |
do{ |
switch(itok.number){ |
case d_ifdef: |
case d_ifndef: |
case d_endif: |
case d_else: |
case d_if: |
case d_elif: |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
directive(); |
inptr=inptr2; |
cha=cha2; |
break; |
default: |
FastTok(0); |
break; |
} |
if(tok==tk_eof)break; |
}while(tok==tk_question); |
} |
|
char *dynamic_var() |
{ |
int start,size; |
char *bstring; |
int use_extract=FALSE; |
|
#define TBUFSIZE 2048 |
#define MTBUFSIZE TBUFSIZE-IDLENGTH |
int curbsize; |
COM_MOD *ocur_mod; |
bstring=(char *)MALLOC(TBUFSIZE); |
curbsize=TBUFSIZE; |
size=0; |
if(tok2==tk_extract)use_extract=TRUE; |
do{ |
start=inptr2-1; |
ocur_mod=cur_mod; |
if(size>(curbsize-IDLENGTH)){ |
curbsize+=TBUFSIZE; |
bstring=(char *)REALLOC(bstring,curbsize); |
} |
nexttok(); |
if(tok==tk_openbrace){ |
bstring[size]='{'; |
size++; |
do{ |
start=inptr2-1; |
ocur_mod=cur_mod; |
if(size>(curbsize-IDLENGTH)){ |
curbsize+=TBUFSIZE; |
bstring=(char *)REALLOC(bstring,curbsize); |
} |
nexttok(); |
if(tok==tk_number){ |
switch(itok.rm){ |
case tk_double: |
case tk_float: |
sprintf(itok.name,"%e",itok.dnumber); |
break; |
case tk_qword: |
sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number); |
break; |
default: |
sprintf(itok.name,"0x%X",itok.number); |
break; |
} |
} |
if(itok.name[0]!=0){ |
strcpy(bstring+size,itok.name); |
size+=strlen(itok.name); |
} |
else{ |
if(cur_mod!=ocur_mod){ |
start=inptr2-2; |
if(start<0)start=0; |
} |
strncpy(bstring+size,(char *)(input+start),inptr2-1-start); |
size+=inptr2-1-start; |
} |
}while(tok!=tk_closebrace&&tok!=tk_eof); |
if(tok!=tk_eof)continue; |
} |
if(tok==tk_number){ |
switch(itok.rm){ |
case tk_double: |
case tk_float: |
sprintf(itok.name,"%e",itok.dnumber); |
break; |
case tk_qword: |
sprintf(itok.name,"0x%X%08X",itok.lnumber>>16,itok.number); |
break; |
default: |
sprintf(itok.name,"0x%X",itok.number); |
break; |
} |
} |
if(itok.name[0]!=0){ |
strcpy(bstring+size,itok.name); |
size+=strlen(itok.name); |
} |
else{ |
if(cur_mod!=ocur_mod){ |
start=inptr2-2; |
if(start<0)start=0; |
} |
strncpy(bstring+size,(char *)(input+start),inptr2-1-start); |
size+=inptr2-1-start; |
} |
if(tok==tk_eof){ |
unexpectedeof(); |
return NULL; |
} |
if(tok==tk_camma&&use_extract==FALSE)break; |
}while(tok!=tk_semicolon); |
// size++; |
bstring[size]=0; |
return bstring; |
} |
|
int SkipBlock() |
{ |
for(int i=1;i!=0;){ |
FastTok(0); |
if(tok==tk_question)CheckDir(); |
switch(tok){ |
case tk_eof: unexpectedeof(); return FALSE; |
case tk_openbrace: i++; break; |
case tk_closebrace: i--; break; |
} |
} |
return TRUE; |
} |
|
int SkipParam() |
{ |
for(int i=1;i!=0;){ |
FastTok(0); |
if(tok==tk_question)CheckDir(); |
switch(tok){ |
case tk_openbracket: i++; break; |
case tk_closebracket: i--; break; |
case tk_eof: unexpectedeof(); return FALSE; |
} |
} |
return TRUE; |
} |
|
int SkipLocalVar() |
{ |
while(tok!=tk_openbrace&&tok!=tk_eof){ |
if(tok==tk_question){ |
CheckDir(); |
continue; |
} |
if(tok==tk_id&&(strcmp(itok.name,"struct")==0||strcmp(itok.name,"union")==0)){ |
do{ |
FastTok(0); |
if(tok==tk_eof){ |
unexpectedeof(); |
return FALSE; |
} |
}while(tok!=tk_semicolon&&tok!=tk_openbrace); |
if(tok==tk_openbrace){ |
FastTok(0); |
if(!SkipBlock())return FALSE; |
} |
} |
FastTok(1); |
} |
return TRUE; |
} |
|
SAVEPAR *SRparam(int save,SAVEPAR *par) //save or restore global param compiler |
{ |
if(save){ |
par=(SAVEPAR *)MALLOC(sizeof(SAVEPAR)); |
par->ooptimizespeed=optimizespeed; |
par->owarning= warning; |
par->odbg= dbg; |
par->odosstring= dosstring; |
par->ouseinline= useinline; |
par->oam32= am32; |
par->oalignword= alignword; |
par->oAlignCycle= AlignCycle; |
par->oidasm= idasm; //àññ |
par->ooptnumber= optnumber; |
par->odivexpand= divexpand; |
par->ooptstr= optstr; //îï |
par->ochip= chip; |
par->oaligncycle= aligncycle; |
par->ouselea= uselea; |
par->oregoverstack= regoverstack; |
return par; |
} |
if(par){ |
optimizespeed=par->ooptimizespeed; |
warning= par->owarning; |
dbg= par->odbg; |
dosstring= par->odosstring; |
useinline= par->ouseinline; |
am32= par->oam32; |
alignword= par->oalignword; |
AlignCycle= par->oAlignCycle; |
idasm= par->oidasm; //àññ |
optnumber= par->ooptnumber; |
divexpand= par->odivexpand; |
optstr= par->ooptstr; //îï |
chip= par->ochip; |
aligncycle= par->oaligncycle; |
uselea = par->ouselea; |
regoverstack= par->oregoverstack; |
free(par); |
} |
return NULL; |
} |
|
void dynamic_proc() |
{ |
int dtok,start,size,line; |
ITOK otok; |
char *bstring; |
idrec *ptr; |
_PROCINFO_ *pinfo; |
if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); |
dtok=tok; |
otok=itok; |
line=linenum2; |
switch(tok){ |
case tk_id: |
case tk_ID: |
string[0]=0; |
case tk_undefproc: |
case tk_declare: |
break; |
default: idalreadydefined(); break; |
} |
if(itok.flag&f_export)preerror("'_export' not use in dynamic functions"); |
bstring=BackString((char *)string); |
start=inptr2-1; |
pinfo=(_PROCINFO_ *)MALLOC(sizeof(_PROCINFO_)); |
if(itok.flag&f_classproc)pinfo->classteg=searchteg; |
else pinfo->classteg=NULL; |
pinfo->warn=warning; |
pinfo->speed=optimizespeed; |
pinfo->lst=(dbg&2)>>1; |
pinfo->typestring=dosstring; |
pinfo->inlinest=useinline; |
pinfo->code32=am32; |
pinfo->align=alignword; |
pinfo->acycle=AlignCycle; |
pinfo->idasm=idasm; |
pinfo->opnum=optnumber; |
pinfo->de=divexpand; |
pinfo->ostring=optstr; |
pinfo->chip=chip; |
pinfo->sizeacycle=aligncycle; |
pinfo->uselea=uselea; |
pinfo->regoverstack=regoverstack; |
nexttok(); |
if(dtok==tk_id||dtok==tk_ID){ |
param[0]=0; |
if(tok2!=tk_closebracket&&(otok.flag&f_typeproc)==tp_fastcall){ |
nexttok(); //ïàðàìåòðû ðåãèñòðîâîé ïðîöåäóðû |
declareparamreg(); |
free(bstring); |
bstring=BackString((char *)param); |
nexttok(); |
inptr=inptr2; |
cha=cha2; |
linenumber=linenum2; |
} |
} |
else{ |
inptr=inptr2; |
cha=cha2; |
if(!SkipParam()){ |
free(bstring); |
return; |
} |
FastTok(1); |
} |
if(tok==tk_semicolon)preerror("error declare dynamic function"); |
if((!SkipLocalVar())||(!SkipBlock())){ |
free(bstring); |
return; |
} |
size=inptr-start+1; |
inptr2=inptr; |
cha2=cha; |
linenum2=linenumber; |
linenumber=line; |
itok=otok; |
strcpy((char *)string,bstring); |
free(bstring); |
bstring=(char *)MALLOC(size+1); |
strncpy(bstring,(char *)(input+start),size); |
bstring[size-1]=';'; |
bstring[size]=0; |
|
// printf("tok=%d %s\n%s\n",dtok,itok.name,bstring); |
itok.size=0; |
tok=tk_proc; |
itok.segm=DYNAMIC; |
if(dtok==tk_id||dtok==tk_ID){ |
int i; |
itok.number=secondcallnum++; |
itok.type=tp_ucnovn; |
if((i=FindUseName(itok.name))!=0)itok.segm=DYNAMIC_USED; |
ptr=addtotree(itok.name); |
if(i){ |
ptr->count=i; |
ptr=itok.rec; |
AddDynamicList(ptr); |
} |
} |
else{ |
if(dtok==tk_undefproc)itok.segm=DYNAMIC_USED; |
updatetree(); |
ptr=itok.rec; |
//11.08.04 23:38 |
strcpy(ptr->recid,itok.name); |
|
if(dtok==tk_undefproc&&(itok.flag&f_classproc))AddDynamicList(ptr); |
} |
ptr->line=linenumber; |
ptr->file=currentfileinfo; |
pinfo->buf=bstring; |
ptr->pinfo=pinfo; |
// ptr->sbuf=bstring; |
// linenumber=linenum2; |
if(searchteg)searchteg=NULL; |
nexttok(); |
} |
|
/* ======= procedure handling ends here ======== */ |
|
int macros(int expectedreturn) |
{ |
int dynamicindex,actualreturn; |
ITOK otok; |
int orettype; |
unsigned int oproctype; |
int otok2; |
unsigned int typep; |
int snum=0; |
actualreturn=(am32==FALSE?tk_word:tk_dword); |
switch(tok){ |
case tk_ID: |
case tk_id: |
dynamicindex=NOT_DYNAMIC; |
break; |
case tk_proc: |
case tk_undefproc: |
case tk_declare: |
dynamicindex=itok.segm; |
actualreturn=itok.rm; |
break; |
default: |
idalreadydefined(); |
return expectedreturn; |
} |
typep=itok.flag; |
otok=itok; |
if(tok==tk_ID)param[0]=0; |
else strcpy(param,(char *)string); |
nexttok(); |
orettype=returntype; |
returntype=actualreturn; //01.08.04 14:45 |
oproctype=current_proc_type; |
if(dynamicindex==NOT_DYNAMIC)doregparams(); |
else{ |
switch(typep&f_typeproc){ |
case tp_cdecl: |
case tp_stdcall: |
snum=swapparam(); |
break; |
case tp_pascal: |
snum=doparams(); |
break; |
case tp_fastcall: |
doregparams(); |
break; |
} |
} |
itok=otok; |
otok2=tok2; |
if(dynamicindex==NOT_DYNAMIC){ |
if((actualreturn=includeit(0))==-1){ |
char holdstr[IDLENGTH+16]; |
sprintf(holdstr,"unknown macro '%s'",itok.name); |
preerror(holdstr); |
} |
} |
else insert_dynamic(TRUE); |
if(actualreturn!=tk_void&&expectedreturn!=tk_ID)convert_returnvalue(expectedreturn,actualreturn); |
returntype=orettype; |
current_proc_type=oproctype; |
if(snum!=0){ |
if(typep&f_retproc)warningdestroyflags(); |
CorrectStack(snum); |
} |
tok2=otok2; |
return actualreturn; |
} |
|
int updatecall(unsigned int which,unsigned int where,unsigned int top) |
/* update output with newly defined location, but only for addresses after |
and including top. return the number of addresses updated. |
which - àäðåñ ïðîöåäóðû |
where - òåêóùèé àäðåñ*/ |
{ |
unsigned int count=0; |
long hold; |
int updates=0; |
while(count<posts){ |
if(((postbuf+count)->type>=CALL_SHORT&&(postbuf+count)->type<=CONTINUE_32)&& |
(postbuf+count)->num==which&&(postbuf+count)->loc>=top){ |
hold=(long)where-(long)(postbuf+count)->loc; |
if((postbuf+count)->type>=CALL_NEAR&&(postbuf+count)->type<=CONTINUE_NEAR){ //NEAR |
hold-=2; |
*(unsigned short *)&output[(postbuf+count)->loc]=(unsigned short)hold; |
} |
else if((postbuf+count)->type>=CALL_32&&(postbuf+count)->type<=CONTINUE_32){//32-BIT |
hold-=4; |
*(unsigned long *)&output[(postbuf+count)->loc]=(unsigned long)hold; |
} |
else{ //SHORT |
hold--; // CALL_SHORT |
if(short_ok(hold))output[(postbuf+count)->loc]=(unsigned char)hold; |
else{ |
if((postbuf+count)->type==BREAK_SHORT)preerror3("BREAK distance too large, use break",(postbuf+count)->line); |
else if((postbuf+count)->type==CONTINUE_SHORT)preerror3("CONTINUE distance too large, use continue",(postbuf+count)->line); |
else preerror3(shorterr,(postbuf+count)->line,(postbuf+count)->file); |
} |
} |
if(hold<127){ |
if((postbuf+count)->type==JMP_NEAR||(postbuf+count)->type==JMP_32)warningjmp("GOTO",(postbuf+count)->line,(postbuf+count)->file); |
if((postbuf+count)->type==BREAK_NEAR||(postbuf+count)->type==BREAK_32)warningjmp("BREAK",(postbuf+count)->line); |
if((postbuf+count)->type==CONTINUE_NEAR||(postbuf+count)->type==CONTINUE_32)warningjmp("CONTINUE",(postbuf+count)->line); |
} |
killpost(count); |
updates++; |
} |
else count++; |
} |
if(updates==1&&hold==0)return -1; |
return(updates); |
} |
|
void define_locallabel() |
{ |
FindOff(string,CS); |
updatecall((unsigned int)updatelocalvar((char *)string,tk_number,outptr),outptr,procedure_start); |
nextexpecting2(tk_colon); |
RestoreStack(); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
} |
|
void addacall(unsigned int idnum,unsigned char callkind) |
{ |
CheckPosts(); |
(postbuf+posts)->num=idnum; |
(postbuf+posts)->loc=outptr+1; |
(postbuf+posts)->type=callkind; |
(postbuf+posts)->line=(unsigned short)linenumber; |
(postbuf+posts)->file=(unsigned short)currentfileinfo; |
posts++; |
} |
|
unsigned int dofrom() // returns number of bytes read from FROM file |
{ |
int filehandle; |
long filesize; |
if(tok!=tk_string){ |
stringexpected(); |
return(0); |
} |
filehandle=open((char *)string3,O_BINARY|O_RDONLY); |
if(filehandle==-1){ |
unableopenfile((char *)string3); |
return(0); |
} |
if((filesize=getfilelen(filehandle))==-1L){ |
preerror("Unable to determine FROM file size"); |
close(filehandle); |
return(0); |
} |
if(am32==FALSE&&filesize>=0xFFFFL){ |
preerror("FROM file too large"); |
close(filehandle); |
return(0); |
} |
LoadData(filesize,filehandle); |
return filesize; |
} |
|
unsigned int doextract() // returns number of bytes EXTRACTed |
{ |
unsigned int sizetoread; |
int filehandle; |
long filesize,startpos; |
if(tok!=tk_string){ |
stringexpected(); |
return(0); |
} |
filehandle=open((char *)string3,O_BINARY|O_RDONLY); |
if(filehandle==-1){ |
unableopenfile((char *)string3); |
return(0); |
} |
nexttok(); |
expecting(tk_camma); |
if(tok!=tk_number){ |
numexpected(); |
return(0); |
} |
startpos=doconstlongmath(); |
expecting(tk_camma); |
if(tok!=tk_number){ |
numexpected(); |
return(0); |
} |
sizetoread=doconstlongmath(); |
if((filesize=getfilelen(filehandle))==-1L){ |
preerror("Unable to determine EXTRACT file size"); |
close(filehandle); |
return(0); |
} |
if(filesize<=startpos){ |
preerror("EXTRACT offset exceeds the length of the file"); |
close(filehandle); |
return(0); |
} |
if(sizetoread==0)sizetoread=filesize-startpos; |
if(am32==FALSE&&sizetoread>=0xFFFFL){ |
preerror("Block to EXTRACT exceeds 64K"); |
close(filehandle); |
return(0); |
} |
lseek(filehandle,startpos,0); // error checking required on this |
LoadData(sizetoread,filehandle); |
return sizetoread; |
} |
|
void LoadData(unsigned int size,int filehandle) |
{ |
if(splitdata){ |
while(((unsigned long)size+(unsigned long)outptrdata)>=outdatasize){ |
if(CheckDataSize()==0)break; |
} |
if((unsigned int)read(filehandle,outputdata+outptrdata,size)!=size)errorreadingfile((char *)string3); |
outptrdata+=size; |
} |
else{ |
while(((unsigned long)size+(unsigned long)outptr)>=outptrsize){ |
if(CheckCodeSize()==0)break; |
} |
if((unsigned int)read(filehandle,output+outptr,size)!=size)errorreadingfile((char *)string3); |
outptr+=size; |
outptrdata=outptr; |
} |
close(filehandle); |
} |
|
void op66(int ctok) |
{ |
if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){ |
if(cpu<3)cpu=3; |
op(0x66); |
} |
} |
|
int op67(int ctok) |
{ |
if((am32==FALSE&&ctok==r32)||(am32!=FALSE&&ctok==r16)){ |
if(cpu<3)cpu=3; |
op(0x67); |
return TRUE; |
} |
return FALSE; |
} |
|
void outseg(ITOK *outtok,unsigned int locadd) |
{ |
int rmm1; |
rmm1=outtok->rm&7; |
if(outtok->sib!=CODE16){ |
if(am32==FALSE)op(0x67); |
if(rmm1==4)locadd++; |
} |
else if(am32!=FALSE)op(0x67); |
switch(outtok->segm){ |
case ES: op(0x26); break; |
case CS: op(0x2E); break; |
case FS: op(0x64); |
if(cpu<3)cpu=3; |
break; |
case GS: op(0x65); |
if(cpu<3)cpu=3; |
break; |
case SS: |
if(outtok->sib==CODE16){ |
if(rmm1!=2&&rmm1!=3&&!(rmm1==6&&outtok->rm!=6))op(0x36); |
} |
else{ |
if(rmm1==4){ |
rmm1=outtok->sib&7; |
if(rmm1!=4){ |
if(rmm1==5){ |
if(outtok->rm==4)op(0x36); |
break; |
} |
op(0x36); |
} |
} |
else if(rmm1==5){ |
if(outtok->rm==5)op(0x36); |
else break; |
} |
else op(0x36); |
} |
break; |
case DS: |
if(outtok->sib==CODE16){ |
if(rmm1==2||rmm1==3||(rmm1==6&&outtok->rm!=6))op(0x3E); |
} |
else{ |
if(rmm1==4){ |
rmm1=outtok->sib&7; |
if(rmm1==4||(rmm1==5&&outtok->rm!=4))op(0x3e); |
} |
else if(rmm1==5&&outtok->rm!=5)op(0x3e); |
} |
} |
CheckPosts(); |
if(outtok->post!=0&&outtok->post!=UNDEF_OFSET){ |
if((outtok->flag&f_extern)){ |
(postbuf+posts)->type=EXT_VAR; |
(postbuf+posts)->num=outtok->number&0xFFFF; |
outtok->number>>=16; |
} |
else if(outtok->post==USED_DIN_VAR){ |
(postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32); |
// printf("Add tok=%d %08X sib=%d %s\n",outtok->rec->rectok,outtok->rec->right,outtok->rec->recsib,outtok->rec->recid); |
if(outtok->rec->rectok==tk_structvar&&outtok->rec->recsib==tp_gvar){ |
(postbuf+posts)->num=(int)outtok->rec;//02.09.05 17:10 ->right; |
} |
else (postbuf+posts)->num=(int)outtok->rec; |
} |
// else if((outtok->flag&f_dataseg))(postbuf+posts)->type=(unsigned short)(am32==0?DATABLOCK_VAR:DATABLOCK_VAR32); |
else (postbuf+posts)->type=(unsigned short)(am32==0?POST_VAR:POST_VAR32); |
(postbuf+posts)->loc=outptr+locadd; |
posts++; |
} |
else if(outtok->flag&f_reloc){ |
(postbuf+posts)->type=(unsigned short)(am32==0?FIX_VAR:FIX_VAR32); |
(postbuf+posts)->loc=outptr+locadd; |
posts++; |
} |
} |
|
int addpoststring(int segm,int len,int term) /* add a string to the post queue */ |
{ |
int i; |
int returnvalue; |
if((returnvalue=FindDublString(segm,len,term))!=-1)return returnvalue; |
CheckPosts(); |
(postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32); |
(postbuf+posts)->loc=(segm==CS?outptr:outptrdata); |
(postbuf+posts)->num=segm; |
posts++; |
returnvalue=poststrptr; |
if((int)(len+poststrptr+1)>=sbufstr){ |
sbufstr+=SIZEBUF; |
bufstr=(char *)REALLOC(bufstr,sbufstr); |
} |
for(i=0;i<len;i++,poststrptr++)bufstr[poststrptr]=string[i]; |
switch(term&3){ |
case zero_term: |
if(term&s_unicod){ |
poststrptr++; |
bufstr[poststrptr]=0; |
} |
bufstr[poststrptr]=0; |
poststrptr++; |
break; |
case dos_term: |
if(term&s_unicod){ |
bufstr[poststrptr]=0; |
poststrptr++; |
} |
bufstr[poststrptr]='$'; |
poststrptr++; |
break; |
} |
return(returnvalue); |
} |
|
int FindDublString(int segm,unsigned int len,int term) |
{ |
STRING_LIST ins,outs; |
void *nextstr=liststring,*prevstr=NULL; |
ins.len=len; |
ins.next=NULL; |
ins.type=term; |
/* if(splitdata){ //ðàçäåëåíûå äàíûå è êîä |
ins.plase=0; |
ins.ofs=outptrdata; |
} |
else{*/ |
ins.plase=POST_STRING; |
ins.ofs=poststrptr; |
// } |
|
while(nextstr!=NULL){ |
memcpy(&outs,nextstr,sizeof(STRING_LIST)); |
if(term==outs.type&&len<=outs.len){ |
char *instr,*outstr; |
outstr=(char *)nextstr+sizeof(STRING_LIST)+outs.len-1; |
instr=(char *)string+len-1; |
char c; |
int i,j; |
for(i=len,j=outs.len;i!=0;j--,i--,instr--,outstr--){ |
c=*instr; |
if(c!=*outstr)break; |
} |
if(i==0){ //íàéäåíà ñòðîêà |
if(!optstr)return -1; |
warningstring(); |
if(outs.plase==0){ //óæå â ôàéëå |
AddReloc(DS); |
return outs.ofs+j; |
} |
CheckPosts(); |
(postbuf+posts)->type=(unsigned short)(am32==FALSE?POST_STRING:POST_STRING32); |
(postbuf+posts)->loc=(segm==CS?outptr:outptrdata); |
(postbuf+posts)->num=segm; |
posts++; |
return outs.ofs+j; |
} |
} |
prevstr=nextstr; |
nextstr=outs.next; |
} |
outs.next=(void *)MALLOC(sizeof(STRING_LIST)+len); |
memcpy(outs.next,&ins,sizeof(STRING_LIST)); |
if(len!=0)memcpy((char *)outs.next+sizeof(STRING_LIST),&string,len); |
if(prevstr!=NULL)memcpy(prevstr,&outs,sizeof(STRING_LIST)); |
else liststring=outs.next; |
return -1; |
} |
|
void killpost(unsigned int poz) |
{ |
posts--; |
memcpy((postinfo *)(postbuf+poz),(postinfo *)(postbuf+posts),sizeof(postinfo)); |
} |
|
void dopoststrings() |
{ |
unsigned int addvalue,i; |
if(poststrptr==0)return; |
if(splitdata){ |
addvalue=outptrdata; |
if((outptrdata+poststrptr)>=outdatasize)CheckDataSize(); |
} |
else{ |
addvalue=outptr; |
if((outptr+poststrptr)>=outptrsize)CheckCodeSize(); |
} |
datasize+=poststrptr; |
if(dbg&2)AddDataNullLine(3); |
memcpy(&outputdata[outptrdata],bufstr,poststrptr); |
outptrdata+=poststrptr; |
if(!splitdata)outptr=outptrdata; |
for(i=0;i<posts;i++){ |
int segm=(postbuf+i)->num; |
if((postbuf+i)->type==POST_STRING){ |
if(segm==CS)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)addvalue; |
else *(unsigned short *)&outputdata[(postbuf+i)->loc]+=(unsigned short)addvalue; |
if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR; |
else if(FixUp==FALSE)killpost(i--); |
else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR:FIX_CODE); |
} |
else if((postbuf+i)->type==POST_STRING32){ |
if(segm==CS)*(unsigned int *)&output[(postbuf+i)->loc]+=addvalue; |
else *(unsigned int *)&outputdata[(postbuf+i)->loc]+=addvalue; |
if(splitdata&&modelmem==TINY)(postbuf+i)->type=(unsigned short)DATABLOCK_VAR32; |
else if(FixUp==FALSE)killpost(i--); |
else (postbuf+i)->type=(unsigned short)(segm==DS?FIX_VAR32:FIX_CODE32); |
} |
} |
poststrptr=0; /* reset the poststrptr */ |
STRING_LIST ins; |
void *nextstr=liststring; |
while(nextstr!=NULL){ |
memcpy(&ins,nextstr,sizeof(STRING_LIST)); |
if(ins.plase!=0){ |
ins.plase=0; |
ins.ofs+=addvalue; |
memcpy(nextstr,&ins,sizeof(STRING_LIST)); |
} |
nextstr=ins.next; |
} |
if(dbg&2)AddCodeNullLine(); |
} |
|
void insertcode() // force code procedure at specified location |
{ |
nexttok(); |
testInitVar(FALSE); |
if((itok.flag&f_extern)!=0){ |
notexternfun(); |
return; |
} |
int tproc=itok.flag&f_typeproc; |
setuprm(); |
switch(tok){ |
case tk_undefproc: |
case tk_declare: |
tok=tk_proc; |
itok.number=outptr; |
updatecall((unsigned int)updatetree(),(unsigned int)itok.number,0); |
if(tproc==tp_fastcall){ |
if(includeit(1)==-1)thisundefined(itok.name); |
} |
else if(includeproc()==-1)thisundefined(itok.name); |
break; |
case tk_id: |
case tk_ID: |
tok=tk_proc; |
itok.number=outptr; |
string[0]=0; |
itok.type=tp_ucnovn; |
addtotree(itok.name); |
if(tproc==tp_fastcall){ |
if(includeit(1)==-1)thisundefined(itok.name); |
} |
else if(includeproc()==-1)thisundefined(itok.name); |
break; |
case tk_proc: |
if(itok.segm<NOT_DYNAMIC)insert_dynamic(); |
else preerror("Function already inserted in code"); |
break; |
default: idalreadydefined(); break; |
} |
nextexpecting2(tk_openbracket); |
while(tok!=tk_eof&&tok!=tk_closebracket)nexttok(); |
if(tok==tk_eof)unexpectedeof(); |
else nextseminext(); |
} |
|
/************ some of the dynamic procedure support functions *************/ |
|
void insert_dynamic(int insert) |
{ |
unsigned char *oinput; |
int oinptr; |
unsigned char ocha; |
int oline; |
int ofile; |
char *ostartline; |
int oendinptr; |
structteg *osearchteg; |
int oinsert; |
_PROCINFO_ *pinfo; |
SAVEPAR *par; |
if(insert){ |
osearchteg=searchteg; |
searchteg=NULL; |
} |
// printf("cur_mod=%08X\n",cur_mod); |
oinsert=insert; |
oinput=input; |
oinptr=inptr2; |
ocha=cha2; |
oline=linenum2; |
ofile=currentfileinfo; |
(startfileinfo+currentfileinfo)->stlist=staticlist; |
oendinptr=endinptr; |
endoffile=0; |
ostartline=startline; |
idrec *ptr=itok.rec; |
pinfo=ptr->pinfo; |
input=(unsigned char *)pinfo->buf; |
inptr2=1; |
startline=(char *)input; |
cha2=input[0]; |
endinptr=strlen((char *)input); |
endinput=startline+endinptr; |
linenumber=linenum2=ptr->line; |
currentfileinfo=ptr->file; |
staticlist=(startfileinfo+currentfileinfo)->stlist; |
par=SRparam(TRUE,NULL); |
warning=pinfo->warn; |
optimizespeed=pinfo->speed; |
dosstring=pinfo->typestring; |
useinline=pinfo->inlinest; |
am32=pinfo->code32; |
alignword=pinfo->align; |
AlignCycle=pinfo->acycle; |
idasm=pinfo->idasm; |
optnumber=pinfo->opnum; |
divexpand=pinfo->de; |
optstr=pinfo->ostring; |
chip=pinfo->chip; |
aligncycle=pinfo->sizeacycle; |
uselea=pinfo->uselea; |
regoverstack=pinfo->regoverstack; |
if(pinfo->classteg!=NULL){ |
/*if((itok.flag&f_static)==0)*/searchteg=(structteg *)pinfo->classteg; |
insert=0; |
} |
if(pinfo->lst)dbg|=2; |
else dbg&=0xFD; |
// puts(itok.name); |
if(!insert){ |
procedure_start=outptr; |
if(dbg){ |
if(dbg&2){ |
char m1[130]; |
//11.08.04 23:39 |
// if(searchteg)sprintf(m1,"%s::%s()",searchteg->name,itok.name); |
// else sprintf(m1,"%s()",itok.name); |
sprintf(m1,"%s()",itok.name); |
|
AddCodeNullLine(m1); |
} |
else AddLine(); |
} |
if(AlignProc)AlignCD(CS,alignproc); |
// puts((char *)input); |
if(pinfo->classteg==NULL)itok.flag&=~f_static; |
setproc(1); |
dopoststrings(); |
} |
else insertproc(); |
input=oinput; |
inptr2=oinptr; |
cha2=ocha; |
linenum2=oline; |
// printf("cur_mod=%08X\n",cur_mod); |
(startfileinfo+currentfileinfo)->stlist=staticlist; |
currentfileinfo=ofile; |
staticlist=(startfileinfo+currentfileinfo)->stlist; |
endinptr=oendinptr; |
endoffile=0; |
startline=ostartline; |
SRparam(FALSE,par); |
if(oinsert)searchteg=osearchteg; |
else searchteg=NULL; |
// if(insert)nexttok(); |
// printf("tok=%d %08X\n",tok,cur_mod); |
} |
|
idrec *addtotree(char *keystring)//äîáàâèòü ñòðîêó â äåðåâî |
{ |
struct idrec *ptr,*newptr; |
int cmpresult; |
//âûäåëèòü ïàìÿòü ïîä íîâóþ ïðîö |
newptr=(struct idrec *)MALLOC(sizeof(struct idrec)); |
ptr=(itok.flag&f_static)!=0?staticlist:treestart; //íà÷àëî äåðåâà |
if(ptr==NULL)((itok.flag&f_static)!=0?staticlist:treestart)=newptr;//íà÷àëî äåðåâà |
else{ //ïîèñê ñòðîêè â äåðåâå |
while(((cmpresult=strcmp(ptr->recid,keystring))<0&&ptr->left!=NULL)|| |
(cmpresult>0&&ptr->right!=NULL))ptr=(cmpresult<0?ptr->left:ptr->right); |
(cmpresult<0?ptr->left:ptr->right)=newptr; |
} |
strcpy(newptr->recid,keystring);//ñêîïèð íàçâàíèå |
newptr->newid=NULL; |
if(string[0]!=0)newptr->newid=BackString((char *)string); |
newptr->rectok=tok; |
newptr->recnumber=itok.number; |
newptr->recsegm=itok.segm; |
newptr->recrm=itok.rm; |
newptr->recpost=itok.post; |
newptr->flag=itok.flag; |
newptr->recsize=itok.size; |
newptr->left=newptr->right=NULL; |
newptr->sbuf=NULL; |
newptr->recsib=itok.sib; |
newptr->line=linenumber; |
newptr->file=currentfileinfo; |
newptr->count=0; |
newptr->type=itok.type; |
newptr->npointr=itok.npointr; |
itok.rec=newptr; |
return newptr; |
} |
|
long updatetree() // returns the old number value |
{ |
struct idrec *ptr; |
long hold; |
ptr=itok.rec; |
if(ptr==0)internalerror("address record not found when update tree"); |
if(ptr->newid)free(ptr->newid); |
ptr->newid=NULL; |
if(string[0]!=0)ptr->newid=BackString((char *)string); |
ptr->rectok=tok; |
hold=ptr->recnumber; |
ptr->recnumber=itok.number; |
ptr->recsegm=itok.segm; |
ptr->recrm=itok.rm; |
ptr->flag=itok.flag; |
ptr->recsize=itok.size; |
ptr->recsib=itok.sib; |
return hold; |
} |
|
/* --------------- local variable handling starts here ----------------- */ |
|
unsigned int updatelocalvar(char *str,int tok4,unsigned int num) |
{ |
struct localrec *ptr; |
unsigned int retvalue; |
treelocalrec *ntlr=tlr; |
while(ntlr&&ntlr->level>1)ntlr=ntlr->next; |
for(ptr=ntlr->lrec;;ptr=ptr->rec.next){ |
if(strcmp(ptr->rec.recid,str)==0){ |
retvalue=ptr->rec.recnumber; |
ptr->rec.rectok=tok4; |
ptr->rec.recnumber=num; |
break; |
} |
if(ptr->rec.next==NULL)break; |
} |
return(retvalue); |
} |
|
localrec * addlocalvar(char *str,int tok4,unsigned int num,int addmain) |
{ |
localrec *ptr,*newptr; |
localrec *uptr; |
treelocalrec *ntlr; |
if(addmain){ |
ntlr=tlr; |
while(ntlr&&ntlr->level>1)ntlr=ntlr->next; |
uptr=ntlr->lrec; |
} |
else uptr=tlr->lrec; |
newptr=(struct localrec *)MALLOC(sizeof(struct localrec)); |
|
if(uptr==NULL){ |
if(addmain)ntlr->lrec=newptr; |
else tlr->lrec=newptr; |
} |
else{ |
ptr=uptr; |
while(ptr->rec.next!=NULL)ptr=ptr->rec.next; |
ptr->rec.next=newptr; |
} |
strcpy(newptr->rec.recid,str); |
newptr->rec.rectok=tok4; |
newptr->rec.recnumber=num; |
newptr->rec.next=NULL; |
newptr->rec.right=NULL; |
newptr->rec.recsize=0; |
newptr->fuse=NOTINITVAR; |
newptr->rec.type=tp_ucnovn; |
newptr->rec.flag=0; |
newptr->rec.npointr=0; |
newptr->rec.recpost=LOCAL; |
newptr->li.count=0; |
newptr->li.start=linenumber; |
return newptr; |
} |
|
void KillTegList(structteg *tteg) |
{ |
if(tteg){ |
KillTegList(tteg->left); |
KillTegList(tteg->right); |
if(tteg->baza)free(tteg->baza); |
free(tteg); |
} |
} |
|
void killlocals(/*int endp*/) |
/* Clear and free the local linked list, check for any unresolved local |
jump labels. */ |
{ |
/* if(endp){ |
dopoststrings(); |
for(int i=0;i<posts;i++){ |
// printf("%d type=%d num=%08X\n",i+1,(postbuf+i)->type,(postbuf+i)->num); |
if((postbuf+i)->type==DIN_VAR||(postbuf+i)->type==DIN_VAR32){ |
idrec *ptr=(idrec *)(postbuf+i)->num; |
// printf("sib=%d num=%08X %s\n",ptr->recsib,ptr->recnumber,ptr->recid); |
if(ptr->recsib!=tp_gvar)continue; |
puts("recsib=tp_gvar"); |
if(ptr->recpost==USED_DIN_VAR){ |
unsigned int otok,otok2; |
ITOK oitok; |
oitok=itok; |
otok=tok; |
otok2=tok2; |
setdindata(ptr,i); |
itok=oitok; |
tok=otok; |
tok2=otok2; |
} |
else{ |
if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber); |
else *(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber; |
} |
if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32); |
else killpost(i--); |
} |
} |
dopoststrings(); |
} |
*/ |
treelocalrec *ftlr,*ftlr1; |
struct localrec *ptr, *ptr1; |
for(ftlr=btlr;ftlr!=NULL;){ |
ftlr1=ftlr; |
for(ptr=ftlr->lrec;ptr!=NULL;){ |
ptr1=ptr; |
if(ptr->rec.rectok==tk_locallabel){ /* check for unresolved labels */ |
char holdstr[32+IDLENGTH]; |
sprintf(holdstr,"local jump label '%s' unresolved",ptr1->rec.recid); |
preerror(holdstr); |
} |
// printf("type=%d post=%08X %s\n",ptr->rec.type,ptr->rec.recpost,ptr->rec.recid); |
if(ptr->rec.rectok==tk_structvar){ |
if(ptr->rec.count==0){ |
warningnotused(ptr->rec.recid,5); |
if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf); |
} |
} |
else if(ptr->fuse<USEDVAR){ |
if(ptr->rec.type==tp_localvar||ptr->rec.type==tp_postvar||ptr->rec.type==tp_gvar)warningnotused(ptr->rec.recid,3); |
else if(ptr->rec.type==tp_paramvar)warningnotused(ptr->rec.recid,4); |
if(ptr->rec.type==tp_gvar)free(ptr->rec.sbuf); |
} |
ptr=ptr->rec.next; |
if(ptr1->rec.recpost!=USED_DIN_VAR)free(ptr1); |
} |
ftlr=ftlr->next; |
free(ftlr1); |
} |
btlr=NULL; |
paramsize=0; |
localsize=0; |
KillTegList(ltegtree); |
ltegtree=NULL; |
} |
|
/* ================ input procedures start ================= */ |
int loadinputfile(char *inpfile) //ñ÷èòûâàíèå ôàéëà â ïàìÿòü |
{ |
unsigned long size; |
int filehandle; |
if((filehandle=open(inpfile,O_BINARY|O_RDONLY))==-1)return -2; |
if((size=getfilelen(filehandle))==0){ |
badinfile(inpfile); |
close(filehandle); |
return(-1); |
} |
if(totalmodule==0){ |
startfileinfo=(struct FILEINFO *)MALLOC(sizeof(FILEINFO)); |
totalmodule=1; |
currentfileinfo=0; |
} |
else{ //ïîèñê åìåíè ôàéëà â ñïèñêå îáðàáîòàííûõ |
for(currentfileinfo=0;currentfileinfo<totalmodule;currentfileinfo++){ |
if(stricmp(inpfile,(startfileinfo+currentfileinfo)->filename)==0)break; |
} |
if(currentfileinfo!=totalmodule){ |
if(crif!=FALSE)return 1; |
goto cont_load; |
} |
totalmodule++; |
startfileinfo=(struct FILEINFO *)REALLOC(startfileinfo,sizeof(FILEINFO)*(totalmodule)); |
} |
|
(startfileinfo+currentfileinfo)->stlist=NULL; |
(startfileinfo+currentfileinfo)->filename=(char *)MALLOC(strlen(inpfile)+1); |
strcpy((startfileinfo+currentfileinfo)->filename,inpfile); |
(startfileinfo+currentfileinfo)->numdline=0; |
//GetFileTime(filehandle,&(startfileinfo+currentfileinfo)->time); // bug |
// getftime(filehandle,&(startfileinfo+currentfileinfo)->time); |
cont_load: |
staticlist=(startfileinfo+currentfileinfo)->stlist; |
input=(unsigned char *)MALLOC(size+1); |
printf("%08lX %s %lu\n",input,inpfile,size); |
if((endinptr=read(filehandle,input,size))!=size){ |
printf("%d\n",endinptr); |
|
errorreadingfile(inpfile); |
close(filehandle); |
return(-1); |
} |
close(filehandle); |
return(0); |
} |
|
void notnegit(int notneg) |
/* produce NOT .. or NEG .. */ |
{ |
int wordadd=0,i=0; |
getoperand(); |
switch(tok){ |
case tk_reg: wordadd=1; op66(r16); |
ClearReg(itok.number); |
case tk_beg: |
if(optimizespeed&&(chip==5||chip==6)){ |
if(wordadd==0&&itok.number==AL)outword(0xFF34); |
else{ |
if(wordadd)op(0x83); |
else op(0x80); |
op(0xF0+itok.number); |
op(0xFF); |
} |
if(notneg){ |
if(wordadd){ |
op66(r16); |
op(0x40+itok.number); |
} |
else{ |
op(0xFE); |
op(0xC0+itok.number); |
} |
} |
} |
else{ |
op(0xF6+wordadd); |
op(0xD0+notneg+itok.number); |
} |
if(wordadd==0)ClearReg(itok.number&3); |
break; |
case tk_wordvar: |
case tk_intvar: wordadd=1; |
i=1; |
case tk_bytevar: |
case tk_charvar: |
i++; |
CheckAllMassiv(bufrm,i,&strinf); |
if(wordadd)op66(r16); |
outseg(&itok,2); |
if((!notneg)&&optimizespeed&&(chip==5||chip==6)){ |
op(wordadd!=0?0x83:0x80); |
op(0x30+itok.rm); |
outaddress(&itok); |
op(0xFF); |
} |
else{ |
op(0xF6+wordadd); |
op(0x10+notneg+itok.rm); |
outaddress(&itok); |
} |
KillVar(itok.name); |
break; |
case tk_reg32: |
op66(r32); |
if(optimizespeed&&(chip==5||chip==6)){ |
op(0x83); |
outword(0xFFF0+itok.number); |
if(notneg){ |
op66(r32); |
op(0x40+itok.number); |
} |
} |
else{ |
op(0xF7); |
op(0xD0+notneg+itok.number); |
} |
if(cpu<3)cpu=3; |
ClearReg(itok.number); |
break; |
case tk_reg64: |
int r1,r2; |
r1=itok.number&255; |
r2=itok.number/256; |
op66(r32); |
op(0xF7); |
op(0xD0+notneg+r2); // NEG reg |
op66(r32); |
op(0xF7); |
op(0xD0+notneg+r1); // NEG reg |
op66(r32); |
op(0x83); |
op(0xD8+r2); |
op(0); |
ClearReg(r1); |
ClearReg(r2); |
break; |
case tk_longvar: |
case tk_dwordvar: |
CheckAllMassiv(bufrm,4,&strinf); |
op66(r32); |
outseg(&itok,2); |
if((!notneg)&&optimizespeed&&(chip==5||chip==6)){ |
op(0x83); |
op(0x30+itok.rm); |
outaddress(&itok); |
op(0xFF); |
} |
else{ |
op(0xF7); |
op(0x10+notneg+itok.rm); |
outaddress(&itok); |
} |
if(cpu<3)cpu=3; |
KillVar(itok.name); |
break; |
case tk_qword: |
itok.number+=4; |
compressoffset(&itok); |
for(i=0;i<2;i++){ |
CheckAllMassiv(bufrm,8,&strinf); |
op66(r32); |
outseg(&itok,2); |
op(0xF7); |
op(0x10+notneg+itok.rm); |
outaddress(&itok); |
if(i==1)break; |
itok.number-=4; |
compressoffset(&itok); |
} |
itok.number-=4; |
compressoffset(&itok); |
CheckAllMassiv(bufrm,8,&strinf); |
op66(r32); |
outseg(&itok,2); |
op(0x83); op(0x18+itok.rm); |
outaddress(&itok); |
op(0); |
KillVar(itok.name); |
if(cpu<3)cpu=3; |
break; |
case tk_doublevar: |
i=4; |
case tk_floatvar: |
if(notneg!=8)illegalfloat(); |
CheckAllMassiv(bufrm,4+i,&strinf); |
outseg(&itok,2); //fld var |
op(0xd9+i); |
op(itok.rm); |
outaddress(&itok); |
outword(0xe0d9); //fchs |
outseg(&itok,2);//fstp var |
op(0xd9+i); |
op(itok.rm+0x18); |
outaddress(&itok); |
fwait3(); |
break; |
default: varexpected(0); |
} |
} |
|
void setreturn() |
{ |
if(numreturn){ |
unsigned int pos,dist; |
//int j=0; |
//restart: |
for(int i=0;i<numreturn;i++){ |
// if(!(listreturn+i)->use)continue; |
pos=(listreturn+i)->loc; |
dist=outptr-pos; |
if((listreturn+i)->type==tk_RETURN){ |
dist--; |
// if(dist){ |
if(dist>127/*&&i>=j*/)jumperror((listreturn+i)->line,mesRETURN); |
output[pos]=(unsigned char)dist; |
/* } |
else{ |
outptr-=2; |
j=i; |
(listreturn+i)->use=FALSE; |
goto restart; |
}*/ |
} |
else{ |
dist-=(am32==0?2:4); |
// if(dist){ |
if(dist<128/*&&i>=j*/)warningjmp(mesRETURN,(listreturn+i)->line,currentfileinfo); |
if(am32)*(unsigned long *)&output[pos]=dist; |
else*(unsigned short *)&output[pos]=(unsigned short)dist; |
/* } |
else{ |
outptr-=3; |
if(am32)outptr-=2; |
j=i; |
(listreturn+i)->use=FALSE; |
goto restart; |
}*/ |
} |
} |
free(listreturn); |
listreturn=NULL; |
numreturn=0; |
} |
} |
|
void RestoreSaveReg() |
{ |
if(psavereg->all){ |
op(0x61); |
addESP-=am32==FALSE?16:32; |
} |
else{ |
for(int i=7;i>=0;i--){ |
if(psavereg->reg[i]){ |
op66(psavereg->reg[i]); |
op(0x58+i); |
addESP-=am32==FALSE?2:4; |
} |
} |
} |
} |
|
void AddRetList(int pos,int line,int type) |
{ |
if(numreturn==0)listreturn=(RETLIST *)MALLOC(sizeof(RETLIST)); |
else listreturn=(RETLIST *)REALLOC(listreturn,sizeof(RETLIST)*(numreturn+1)); |
(listreturn+numreturn)->loc=pos; |
(listreturn+numreturn)->line=line; |
(listreturn+numreturn)->type=type; |
// (listreturn+numreturn)->use=TRUE; |
if(type==tk_return)jumploc0(); |
else outword(0x00EB); // JMP SHORT |
numreturn++; |
} |
|
void RetProc() |
{ |
if((current_proc_type&f_far)){ |
if((current_proc_type&f_typeproc)==tp_cdecl)retf(); |
else{ |
if(paramsize==0)retf(); /* RETF */ |
else{ |
op(0xCA); |
outword(paramsize); |
} |
} |
} |
else{ |
if((current_proc_type&f_typeproc)==tp_cdecl)ret(); |
else if(current_proc_type==f_interrupt)op(0xCF);//interrupt procedure IRET |
else{ |
if(paramsize==0)ret(); /* RET */ |
else{ |
op(0xC2); |
outword(paramsize); |
} |
} |
} |
} |
|
void doreturn(int typer) /* do return(...); */ |
{ |
char sign=0; |
int line=linenumber; |
char *ofsstr=NULL; |
int i; |
unsigned int oaddESP=addESP; |
if(tok2==tk_openbracket)nexttok(); |
if((ofsstr=GetLecsem(tk_closebracket,tk_semicolon))){ |
int retreg; |
int razr=getrazr(returntype); |
if((retreg=CheckIDZReg(ofsstr,AX,razr))!=NOINREG){ |
GetEndLex(tk_closebracket,tk_semicolon); |
if(razr==r16)tok=tk_reg; |
else if(razr==r32)tok=tk_reg32; |
else tok=tk_beg; |
itok.number=retreg==SKIPREG?AX:retreg; |
goto nn1; |
} |
} |
getoperand(); |
if(tok!=tk_closebracket&&tok!=tk_semicolon){ |
nn1: |
switch(returntype){ |
case tk_int: sign=1; |
case tk_word: do_e_axmath(sign,r16,&ofsstr); break; |
case tk_char: sign=1; |
case tk_byte: doalmath(sign,&ofsstr); break; |
case tk_long: sign=1; |
case tk_dword: do_e_axmath(sign,r32,&ofsstr); break; |
case tk_qword: |
getintoreg64(EAX|(EDX*256)); |
if(itok.type!=tp_stopper&&tok!=tk_eof&&itok.type!=tp_compare)doregmath64(EAX|(EDX*256)); |
break; |
case tk_void: retvoid(); nexttok(); break; |
case tk_double: |
/* if(tok2==tk_closebracket)doregmath64(EAX|(EDX*256)); |
else doeaxfloatmath(tk_reg64); |
break;*/ |
case tk_fpust: |
doeaxfloatmath(tk_fpust); |
break; |
case tk_float: |
if(itok2.type==tp_stopper&&(tok==tk_floatvar||tok==tk_number)){ |
if(tok==tk_floatvar){ |
tok=tk_dwordvar; |
do_e_axmath(0,r32,&ofsstr); |
} |
else doeaxfloatmath(tk_reg32,0,0); |
} |
else{ |
doeaxfloatmath(tk_stackstart,0,0); |
op66(r32); |
op(0x58); //pop eax |
} |
break; |
// default: |
// printf("returntype=%d\n",returntype); |
} |
} |
if(tok==tk_closebracket)nexttok(); |
seminext(); |
if(ofsstr)free(ofsstr); |
clearregstat(); |
#ifdef OPTVARCONST |
ClearLVIC(); |
#endif |
if(typer!=tokens){ |
i=(am32==0?2:4); |
if(typer==tk_RETURN)i=1; |
if(paramsize||localsize)i--; |
if(insertmode||((!optimizespeed)&¶msize&& |
(current_proc_type&f_typeproc)!=tp_cdecl)||psavereg->size>i){ |
if(numblocks>1){ //çàìåíèòü return íà goto |
AddRetList(outptr+1,line,typer); |
retproc=TRUE; |
return; |
} |
else{ |
setreturn(); |
if(insertmode)return; |
} |
} |
} |
if(numblocks==1)setreturn(); //06.09.04 22:20 |
if(!inlineflag)leaveproc(); |
else{ |
AutoDestructor(); |
RestoreStack(); |
RestoreSaveReg(); |
RetProc(); |
} |
retproc=TRUE; |
if(numblocks>1||(numblocks==1&&tok!=tk_closebrace))addESP=oaddESP; |
} |
|
int IsSaveReg() |
{ |
if(psavereg->all)return TRUE; |
for(int i=7;i>=0;i--){ |
if(psavereg->reg[i])return TRUE; |
} |
return FALSE; |
} |
|
void leaveproc() |
{ |
AutoDestructor(); |
RestoreStack(); |
RestoreSaveReg(); |
if(ESPloc==FALSE||am32==FALSE){ |
if(localsize)Leave(); |
else if(paramsize)op(0x5D); /* POP BP */ |
else if(initBP)Leave(); |
} |
else if(localsize){ |
if(short_ok(localsize,TRUE)){ |
outword(0xC483); |
op(localsize); |
} |
else{ |
outword(0xC481); |
outdword(localsize); |
} |
} |
RetProc(); |
} |
|
DLLLIST *FindDLL() |
{ |
DLLLIST *newdll; |
if(listdll!=NULL){ //ñïèñîê DLL íå ïóñò |
for(newdll=listdll;stricmp(newdll->name,(char *)string)!=0;newdll=newdll->next){ |
if(newdll->next==NULL){ //ïîñëåäíÿÿ â ñïèñêå |
newdll->next=(DLLLIST *)MALLOC(sizeof(DLLLIST));//ñîçäàòü íîâóþ |
newdll=newdll->next; |
newdll->next=NULL; |
newdll->num=0; |
newdll->list=NULL; |
strcpy(newdll->name,(char *)string); |
break; |
} |
} |
} |
else{ |
listdll=newdll=(DLLLIST *)MALLOC(sizeof(DLLLIST)); |
newdll->next=NULL; |
newdll->num=0; |
newdll->list=NULL; |
strcpy(newdll->name,(char *)string); |
} |
return newdll; |
} |
|
void declareextern() |
{ |
int next; |
nexttok(); |
if(comfile==file_w32&&strcmp(itok.name,"WINAPI")==0){ |
nexttok(); |
if(tok!=tk_string)stringexpected(); |
DLLLIST *newdll; |
newdll=FindDLL(); |
nextexpecting2(tk_openbrace); //îòêðûòèå ñïèñêà ïðîöåäóð |
APIPROC *listapi=newdll->list; |
returntype=tk_declare; |
do{ |
if(tok==tk_enum)doenum(); |
else if(tok==tk_struct)InitStruct(); |
else{ |
next=TRUE; |
if(testInitVar(FALSE)!=FALSE)preerror("Error declare WINAPI"); |
if(itok.rm==tokens)itok.rm=tk_dword; |
if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word); |
ITOK hitok=itok; |
int htok=tok; |
param[0]=0; |
hitok.sib=hitok.size=-1; |
if(tok2==tk_period){ |
nexttok(); |
if(tok2==tk_number){ |
nexttok(); |
hitok.sib=itok.number; |
} |
} |
if(tok2==tk_at){ |
nexttok(); |
if(tok2==tk_number){ |
nexttok(); |
hitok.size=itok.number; |
} |
} |
else{ |
nextexpecting2(tk_openbracket); |
if((hitok.flag&f_typeproc)==tp_fastcall)declareparamreg(); |
else declareparamstack(); |
} |
if(htok==tk_id||htok==tk_ID){ |
tok=tk_apiproc; |
itok=hitok; |
itok.number=secondcallnum++; |
itok.segm=NOT_DYNAMIC; |
itok.post=dEBX|dEDI|dESI; //05.09.04 01:36 |
strcpy((char *)string,param); |
itok.type=tp_ucnovn; |
if(newdll->num==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC)); //ïåðâàÿ â ñïèñêå |
else listapi=(APIPROC *)REALLOC(listapi,sizeof(APIPROC)*(newdll->num+1)); |
(listapi+newdll->num)->recapi=addtotree(itok.name); |
if(tok2==tk_openbracket){ |
next=0; |
nexttok(); |
IsUses((listapi+newdll->num)->recapi); |
} |
newdll->num++; |
} |
else warningdefined(hitok.name); |
if(next)nexttok(); |
seminext(); |
} |
}while(tok!=tk_closebrace); |
returntype=tokens; |
newdll->list=listapi; |
nexttok(); |
} |
else{ |
itok.flag=f_extern; |
switch(tok){ |
case tk_far: |
case tk_cdecl: |
case tk_pascal: |
case tk_stdcall: |
case tk_fastcall: |
case tk_declare: |
case tk_undefproc: |
case tk_ID: |
case tk_id: |
case tk_float: |
case tk_long: |
case tk_dword: |
case tk_word: |
case tk_byte: |
case tk_char: |
case tk_int: |
case tk_void: |
int j; |
if((j=testInitVar())==FALSE)define_procedure(); |
else if(j==TRUE)globalvar(); |
break; |
case tk_struct: InitStruct(); break; |
default: preerror("Error declare extern"); |
} |
if((!fobj)&&(!sobj))preerror("extern using only for compilation obj files"); |
} |
} |
|
int testInitVar(int checkaldef) |
{ |
unsigned int ffar=0; |
unsigned int fexport=0; |
unsigned int tproc=0; |
unsigned int fretproc=0; |
int rettype=tokens; |
unsigned int flag=itok.flag; |
unsigned int npointr=0; |
if(fstatic){ |
flag|=f_static; |
fstatic=FALSE; |
} |
if(tok==tk_inline){ |
flag=f_inline; |
nexttok(); |
} |
for(;;){ |
if(tok==tk_far)ffar=f_far; |
else if(tok==tk_export)fexport=f_export; |
else if(tok>=tk_pascal&&tok<=tk_fastcall)tproc=tok; |
else if((tok>=tk_void&&tok<=tk_double)||tok==tk_fpust){ |
if(rettype!=tokens)unknowntype(); |
rettype=tok; |
} |
else if(tok==tk_id){ |
if(CheckDef())continue; |
if(tok2==tk_dblcolon)goto classdecl; |
if(tproc==0)tproc=(comfile==file_w32?tp_stdcall:tp_pascal); //òèï ïðîö ïî óìîë÷àíèþ |
else tproc=(tproc-tk_pascal)*2; |
break; |
} |
else if(tok==tk_ID){ |
if(CheckDef())continue; |
if(tok2==tk_dblcolon){ |
classdecl: |
itok.flag=(unsigned int)(flag|ffar|fexport|fretproc|f_classproc); |
itok.rm=rettype; |
itok.npointr=(unsigned short)npointr; |
doclassproc(tproc); |
return 2; |
} |
if(tproc==0)tproc=tp_fastcall; //òèï ïðîö ïî óìîë÷àíèþ |
else tproc=(tproc-tk_pascal)*2; |
break; |
} |
else if(tok==tk_undefproc||tok==tk_declare/*||tok==tk_apiproc*/){ |
|
flag|=itok.flag; //new 18.04.07 12:19 |
|
if(tproc==0){ |
if(CidOrID()==tk_ID)tproc=tp_fastcall; |
else tproc=(comfile==file_w32?tp_stdcall:tp_pascal); |
} |
else tproc=(tproc-tk_pascal)*2; // 17.09.05 17:06 |
if((flag&f_extern)!=0||tproc!=(itok.flag&f_typeproc)|| |
ffar!=(itok.flag&f_far)||(unsigned short)npointr!=itok.npointr|| |
((flag&f_static)&&(itok.flag&f_static)==0)){ |
if(strcmp(itok.name,"main")){ |
if(rettype==itok.rm||(rettype==tokens&&(itok.rm==(am32==0?tk_word:tk_dword))))break; |
// printf("rm=%d rmnew=%d\n",itok.rm,rettype); |
if(checkaldef)redeclare(itok.name); |
} |
} |
break; |
} |
else if(tok==tk_proc||tok==tk_apiproc){ |
if(checkaldef)idalreadydefined(); |
break; |
} |
else if((tok>=tk_bits&&tok<=tk_doublevar)||tok==tk_structvar||tok==tk_pointer){ |
idalreadydefined(); |
return 2; |
} |
else if(tok==tk_mult){ |
do{ |
npointr++; |
nexttok(); |
}while(tok==tk_mult); |
if(rettype==tokens)rettype=am32==FALSE?tk_word:tk_dword; |
continue; |
} |
else if(tok==tk_openbracket){ |
if(tok2!=tk_mult){ |
unuseableinput(); |
return 2; |
} |
if(tproc!=0)tproc=(tproc-tk_pascal)*2; |
itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc); |
itok.rm=rettype; |
itok.npointr=(unsigned short)npointr; |
return TRUE; |
} |
else if((tok>=tk_overflowflag&&tok<=tk_notzeroflag)||tok==tk_minusflag|| |
tok==tk_plusflag)fretproc=(tok-tk_overflowflag+1)*256; |
else if(tok==tk_static)flag|=f_static; |
else if(tok==tk_fpust)rettype=tk_fpust; |
else{ |
unuseableinput(); |
return 2; |
} |
nexttok(); |
} |
itok.flag=(unsigned int)(flag|ffar|tproc|fexport|fretproc); |
itok.rm=rettype; |
itok.npointr=(unsigned short)npointr; |
if(returntype==tk_declare&& |
(tok2==tk_openbracket||tok2==tk_at||tok2==tk_period))return FALSE; |
if(tok2==tk_openbracket)return CheckDeclareProc(); |
if(rettype==tokens){ |
thisundefined(itok.name);//02.09.04 20:55 was unuseableinput(); |
return 2; |
} |
return TRUE; |
/*-----------------23.12.01 02:11------------------- |
rerurn: |
FALSE - åñëè îïðåäåëåíèå, âñòàâêà ïðîöåäóðû |
TRUE - ïåðåìåííàÿ èëè îáúÿâëåíèå ïðîöåäóðû |
2 - îøèáêà èëè îáðàáîòàíî - íèêàêèõ äåéñòâèé íå ïðåäïðèíèìàòü. |
--------------------------------------------------*/ |
} |
|
int CidOrID() |
{ |
unsigned char cha; |
unsigned char *string4=(unsigned char *)itok.name; |
for(;;){ |
cha=*string4; |
if(cha>='a'&&cha<='z')return tk_id; |
if(cha==0)break; |
string4++; |
} |
return tk_ID; |
} |
|
void unpackteg(structteg *tteg) |
{ |
int i; |
elementteg *bazael; |
structteg *newteg; |
int ssize,count; |
idrec *newrec,*ptr; |
if(alignword){ //âûðîâíÿòü íà ÷åòíûé àäðåñ |
if(am32==0){ |
if(postsize%2==1)postsize++; |
} |
else if(ssize==4&&postsize%4!=0)postsize+=4-(postsize%4); |
} |
bazael=tteg->baza; |
string[0]=0; |
for(i=0;i<tteg->numoper;i++){ |
// printf("tok=%d %s\n",(bazael+i)->tok,(bazael+i)->name); |
switch((bazael+i)->tok){ |
case tk_floatvar: |
case tk_longvar: |
case tk_dwordvar: |
case tk_wordvar: |
case tk_bytevar: |
case tk_charvar: |
case tk_intvar: |
case tk_doublevar: |
case tk_qwordvar: |
ssize=GetVarSize((bazael+i)->tok); //ðàçìåð ïåðåìåííîé |
itok.type=tp_ucnovn; |
tok=(bazael+i)->tok; |
count=FindOff((unsigned char *)(bazael+i)->name,VARPOST); |
itok.post=1; |
itok.segm=DS; |
itok.number=postsize; |
itok.flag=tteg->flag; |
itok.size=(bazael+i)->numel*ssize; |
itok.rm=(am32==FALSE?rm_d16:rm_d32); |
itok.npointr=0; |
newrec=addtotree((bazael+i)->name); |
newrec->count=count; |
break; |
case tk_struct: |
case tk_structvar: |
strcpy(itok.name,(bazael+i)->name); |
newteg=(structteg *)(bazael+i)->nteg; |
newrec=(struct idrec *)MALLOC(sizeof(struct idrec)); |
ptr=((tteg->flag&f_static)==0?treestart:staticlist); //íà÷àëî äåðåâà |
if(ptr==NULL)((tteg->flag&f_static)==0?treestart:staticlist)=newrec;//íà÷àëî äåðåâà |
else{ //ïîèñê ñòðîêè â äåðåâå |
while(((ssize=strcmp(ptr->recid,itok.name))<0&&ptr->left!=NULL)||(ssize>0&&ptr->right!=NULL)){ |
ptr=(ssize<0?ptr->left:ptr->right); |
} |
(ssize<0?ptr->left:ptr->right)=newrec; //ñòðîêà ìåíüøå |
} |
newrec->recsib=0; |
strcpy(newrec->recid,itok.name);//ñêîïèð íàçâàíèå |
newrec->newid=(char *)newteg; |
newrec->left=NULL; |
newrec->right=NULL; |
newrec->rectok=tk_structvar; |
newrec->flag=tteg->flag|newteg->flag; |
newrec->line=linenumber; |
newrec->file=currentfileinfo; |
if(FixUp)newrec->flag|=f_reloc; |
newrec->recrm=(bazael+i)->numel; |
newrec->recsize=(bazael+i)->numel*newteg->size; |
newrec->recpost=1; |
count=FindOff((unsigned char *)newrec->recid,VARPOST); |
newrec->count=count; |
break; |
default: |
declareanonim(); |
break; |
} |
} |
AddPostData(tteg->size); |
} |
|
void unpackteg2(structteg *tteg) |
{ |
int i; |
elementteg *bazael; |
structteg *newteg; |
//idrec *newrec,*trec; |
localrec *lrec; |
bazael=tteg->baza; |
string[0]=0; |
for(i=0;i<tteg->numoper;i++){ |
switch((bazael+i)->tok){ |
case tk_floatvar: |
case tk_longvar: |
case tk_dwordvar: |
case tk_wordvar: |
case tk_bytevar: |
case tk_charvar: |
case tk_intvar: |
case tk_doublevar: |
case tk_qwordvar: |
lrec=addlocalvar((bazael+i)->name,(bazael+i)->tok,localsize); |
lrec->rec.recsize=(bazael+i)->numel*GetVarSize((bazael+i)->tok); |
lrec->rec.type=tp_localvar; |
lrec->rec.npointr=0; |
lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4)); |
break; |
case tk_struct: |
case tk_structvar: |
newteg=(structteg *)(bazael+i)->nteg; |
lrec=addlocalvar((bazael+i)->name,tk_structvar,localsize); |
lrec->rec.newid=(char *)tteg; |
lrec->rec.flag=tteg->flag; |
lrec->rec.type=tp_localvar; |
lrec->rec.recrm=(bazael+i)->numel; |
lrec->rec.recsize=(bazael+i)->numel*newteg->size; |
lrec->rec.recpost=LOCAL; |
lrec->rec.recnumber=-lrec->rec.recnumber-Align(lrec->rec.recsize,(am32==FALSE?2:4)); |
break; |
default: |
declareanonim(); |
break; |
} |
} |
localsize+=tteg->size; |
localsize=Align(localsize,(am32==FALSE?2:4)); |
} |
|
unsigned long dounion(int Global,int flag) |
{ |
structteg *tteg; |
int noname=FALSE; |
nexttok(); |
if(tok==tk_openbrace)noname=TRUE; |
else if((tok!=tk_id&&tok!=tk_ID)||FindTeg(Global)||(Global==FALSE&&FindTeg(TRUE))){ |
idalreadydefined(); |
SkipBlock2(); |
return 0; |
} |
if((tteg=CreatTeg(Global,TRUE,noname))!=NULL){ |
if(tok==tk_semicolon){ |
if(noname==TRUE){ |
if(Global)unpackteg(tteg); |
else unpackteg2(tteg); |
if(tteg->baza)free(tteg->baza); |
free(tteg); |
} |
nexttok(); |
} |
else{ |
if(Global)InitStruct2(flag,tteg); |
else return LocalStruct2(flag,0,0,0,tteg); |
} |
} |
else declareunion(); |
return 0; |
} |
|
char *BackString(char *str) |
{ |
char *retbuf=(char *)MALLOC(strlen(str)+1); |
strcpy(retbuf,str); |
return retbuf; |
} |
|
|
void GetFileTime(int fd,struct ftime *buf) |
{ |
/* |
struct stat sb; |
struct tm *tblock; |
fstat(fd,&sb); |
tblock=localtime(&sb.st_atime); |
buf->ft_tsec=tblock->tm_sec; |
buf->ft_min=tblock->tm_min; |
buf->ft_hour=tblock->tm_hour; |
buf->ft_day=tblock->tm_mday; |
buf->ft_month=tblock->tm_mon; |
buf->ft_year=tblock->tm_year-80;*/ |
} |
|
void CheckPosts() |
{ |
if(posts==maxposts){ |
maxposts+=MAXPOSTS; |
postbuf=(postinfo *)REALLOC(postbuf,maxposts*sizeof(postinfo)); |
} |
} |
|
void CheckRealizable() |
{ |
switch(tok){ |
case tk_case: |
case tk_CASE: |
case tk_default: |
case tk_closebrace: |
return; |
} |
if(tok2==tk_colon)return; |
if(notunreach){ |
notunreach=FALSE; |
return; |
} |
warningunreach(); |
// preerror("Unreachable code"); |
} |
|
void AddRegistr(int razr,int reg) |
{ |
if(razr==r8&®>3)reg-=4; |
if(razr==r64){ |
stat_reg[reg&255]=1; |
stat_reg[reg/256]=1; |
} |
else stat_reg[reg]=1; |
} |
|
void ClearRegister() |
{ |
for(int i=0;i<8;i++)stat_reg[i]=0; |
} |
|
int GetRegister(int mode) |
{ |
int reg=SI; |
if(am32!=FALSE||mode){ |
if(stat_reg[AX]==0)reg=AX; |
else if(stat_reg[SI]==0)reg=SI; |
else if(stat_reg[DI]==0)reg=DI; |
else if(stat_reg[BX]==0)reg=BX; |
else if(stat_reg[CX]==0)reg=CX; |
else if(stat_reg[DX]==0)reg=DX; |
} |
else{ |
if(stat_reg[SI]==0)reg=SI; |
else if(stat_reg[DI]==0)reg=DI; |
else if(stat_reg[BX]==0)reg=BX; |
} |
return reg; |
} |
|
void RegAddNum(int reg) |
{ |
if((!structadr.post)&&optnumadd(structadr.number,reg,am32==FALSE?r16:r32,0)!=FALSE)return; |
if(reg==AX)op(5); |
else{ |
op(0x81); |
op(0xC0+reg); |
} |
if(structadr.post)setwordpost(&structadr); |
if(am32)outdword(structadr.number); |
else outword(structadr.number); |
} |
|
void RestoreStack() |
{ |
if(addstack&&sizestack){ |
if(short_ok(sizestack,am32)){ |
outword(0xC483); |
op(sizestack); |
} |
else{ |
outword(0xC481); |
if(am32==FALSE)outword(sizestack); |
else outdword(sizestack); |
} |
// printf("%s(%d)> Restore %d bytes stacks.\n",startfileinfo==NULL?"":(startfileinfo+currentfileinfo)->filename,linenumber,sizestack); |
addESP-=sizestack; |
sizestack=0; |
} |
} |
|
void startblock() |
{ |
treelocalrec *nrec; |
numblocks++; |
// printf("start block %d\n",numblocks); |
nrec=(treelocalrec*)MALLOC(sizeof(treelocalrec)); |
nrec->level=numblocks; |
nrec->lrec=NULL; |
nrec->addesp=addESP; |
nrec->next=tlr; |
tlr=nrec; |
} |
|
void endblock() |
{ |
treelocalrec *orec; |
// printf("end block %d\n",numblocks); |
orec=tlr; |
tlr=tlr->next; |
if(tlr)numblocks=tlr->level; |
else numblocks=0; |
if(orec->lrec==NULL){ |
free(orec); |
return; |
} |
orec->endline=linenumber; |
orec->next=btlr; |
btlr=orec; |
// if(addESP!=orec->addesp)??? |
} |
/* end of TOKC.C */ |