forked from KolibriOS/kolibrios
Added source files C--.
git-svn-id: svn://kolibrios.org@6446 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
829
programs/develop/cmm/switch.cpp
Normal file
829
programs/develop/cmm/switch.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
#define _SWITCH_
|
||||
|
||||
|
||||
|
||||
#include "tok.h"
|
||||
|
||||
|
||||
|
||||
extern int lastcommand; //¯®á«¥¤¨© ®¯¥à â®à ¢ ¡«®ª¥
|
||||
|
||||
|
||||
|
||||
#define MAXCASE 1024
|
||||
|
||||
|
||||
|
||||
FSWI *swtables; //â ¡«¨æ ¨ä®à¬ 権 ®¡ switch
|
||||
|
||||
int numswtable=0; //ç¨á«® ¡«®ª®¢ ¢ í⮩ â ¡«¨æ¥
|
||||
|
||||
char mesSWITCH[]="SWITCH";
|
||||
|
||||
char mesCASE[]="CASE";
|
||||
|
||||
int numexpandcase;
|
||||
|
||||
int numberbreak=0;
|
||||
|
||||
|
||||
|
||||
void CheckJmpSW(int line,int endsw,int startsw,int shortjmp,char *mes)
|
||||
|
||||
{
|
||||
|
||||
int size=startsw-endsw;
|
||||
|
||||
if(shortjmp==FALSE){
|
||||
|
||||
if((unsigned int)size<128)warningjmp(mes,line);
|
||||
|
||||
if(am32==FALSE)*(unsigned short *)&output[endsw-2]=(unsigned short)size;
|
||||
|
||||
else *(unsigned long *)&output[endsw-4]=(unsigned long)size;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if((unsigned int)size>127)jumperror(line,mes);
|
||||
|
||||
output[endsw-1]=(unsigned char) size;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CmpRegNum(int tokr,unsigned long value,int reg)
|
||||
|
||||
{
|
||||
|
||||
if(tokr!=r8){
|
||||
|
||||
op66(tokr); //CMP EAX,val
|
||||
|
||||
if(value==0){
|
||||
|
||||
op(0x85);
|
||||
|
||||
op(0xC0+reg*9); //test AX,AX
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(short_ok(value,tokr==r32?TRUE:FALSE)){
|
||||
|
||||
op(0x83);
|
||||
|
||||
op(0xF8+reg);
|
||||
|
||||
op(value);
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(reg==0)op(0x3D);
|
||||
|
||||
else{
|
||||
|
||||
op(0x81);
|
||||
|
||||
op(0xF8+reg);
|
||||
|
||||
}
|
||||
|
||||
tokr==r32?outdword(value):outword(value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{ //CMP AL,val
|
||||
|
||||
if(value==0){
|
||||
|
||||
op(0x84);
|
||||
|
||||
op(0xC0+reg*9);
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(reg==0)op(0x3c);
|
||||
|
||||
else{
|
||||
|
||||
op(0x80);
|
||||
|
||||
op(0xF8+reg);
|
||||
|
||||
}
|
||||
|
||||
op(value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ScanSwitch(int *numcase,ISW *caseinf,COM_MOD *startmod)
|
||||
|
||||
{
|
||||
|
||||
unsigned char dcha;
|
||||
|
||||
int dtok,line,oinptr,i,otok2;
|
||||
|
||||
//new
|
||||
|
||||
unsigned char *oinput;
|
||||
|
||||
int oendinptr;
|
||||
|
||||
|
||||
|
||||
ITOK otok;
|
||||
|
||||
int retcode=TRUE;
|
||||
|
||||
dtok=tok;
|
||||
|
||||
otok=itok;
|
||||
|
||||
otok2=tok2;
|
||||
|
||||
line=linenum2;
|
||||
|
||||
dcha=cha2;
|
||||
|
||||
oinptr=inptr=inptr2;
|
||||
|
||||
cha=cha2;
|
||||
|
||||
//new
|
||||
|
||||
oinput=input;
|
||||
|
||||
oendinptr=endinptr;
|
||||
|
||||
if(startmod!=cur_mod){
|
||||
|
||||
COM_MOD *pmod=cur_mod;
|
||||
|
||||
while(pmod->next!=startmod){
|
||||
|
||||
pmod=pmod->next;
|
||||
|
||||
}
|
||||
|
||||
input=pmod->input;
|
||||
|
||||
inptr=pmod->inptr;
|
||||
|
||||
endinptr=pmod->endinptr;
|
||||
|
||||
cha=input[inptr];
|
||||
|
||||
inptr++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(SkipParam()){
|
||||
|
||||
FastTok(0);
|
||||
|
||||
if(tok!=tk_openbrace){
|
||||
|
||||
SwTok(tk_openbrace);
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
for(i=1;i!=0;){
|
||||
|
||||
FastTok(1);
|
||||
|
||||
if(tok==tk_question)CheckDir();
|
||||
|
||||
switch(tok){
|
||||
|
||||
case tk_eof:
|
||||
|
||||
unexpectedeof();
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
i=0;
|
||||
|
||||
break;
|
||||
|
||||
case tk_openbrace: i++; break;
|
||||
|
||||
case tk_closebrace: i--; break;
|
||||
|
||||
case tk_id:
|
||||
|
||||
case tk_case:
|
||||
|
||||
case tk_CASE:
|
||||
|
||||
if(i==1){
|
||||
|
||||
if(stricmp(itok.name,"case")==0){
|
||||
|
||||
inptr2=inptr;
|
||||
|
||||
cha2=cha;
|
||||
|
||||
linenum2=linenumber;
|
||||
|
||||
(caseinf+*numcase)->postcase=(itok.name[0]=='c'?FALSE:TRUE);
|
||||
|
||||
nexttok();
|
||||
|
||||
if(tok==tk_number||(tok==tk_minus&&tok2==tk_number)){
|
||||
|
||||
if(*numcase==MAXCASE){
|
||||
|
||||
preerror("Many to use <case>");
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
unsigned long val=doconstlongmath();
|
||||
|
||||
for(int j=0;j<*numcase;j++){
|
||||
|
||||
if(val==(caseinf+j)->value){
|
||||
|
||||
preerror("Duplicate 'case'");
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(caseinf+*numcase)->value=val;
|
||||
|
||||
if(tok==tk_multipoint){
|
||||
|
||||
(caseinf+*numcase)->type=startmulti;
|
||||
|
||||
nexttok();
|
||||
|
||||
val=doconstlongmath();
|
||||
|
||||
numexpandcase+=val-(caseinf+*numcase)->value-1;
|
||||
|
||||
if(val<(caseinf+*numcase)->value){
|
||||
|
||||
preerror("The first value 'case' should be smaller");
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
}
|
||||
|
||||
*numcase=*numcase+1;
|
||||
|
||||
(caseinf+*numcase)->type=endmulti;
|
||||
|
||||
(caseinf+*numcase)->value=val;
|
||||
|
||||
(caseinf+*numcase)->postcase=(caseinf+*numcase-1)->postcase;
|
||||
|
||||
}
|
||||
|
||||
else (caseinf+*numcase)->type=singlcase;
|
||||
|
||||
*numcase=*numcase+1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
numexpected();
|
||||
|
||||
retcode=FALSE;
|
||||
|
||||
}
|
||||
|
||||
inptr=inptr2;
|
||||
|
||||
cha=cha2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(retcode){ //¥á«¨ ¥ ©¤¥® ®è¨¡®ª
|
||||
|
||||
tok=dtok;
|
||||
|
||||
itok=otok;
|
||||
|
||||
linenum2=line;
|
||||
|
||||
cha2=dcha;
|
||||
|
||||
inptr2=oinptr;
|
||||
|
||||
tok2=otok2;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
inptr2=inptr;
|
||||
|
||||
cha2=cha;
|
||||
|
||||
linenum2=linenumber;
|
||||
|
||||
}
|
||||
|
||||
//new
|
||||
|
||||
input=oinput;
|
||||
|
||||
endinptr=oendinptr;
|
||||
|
||||
|
||||
|
||||
return retcode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void doswitch()
|
||||
|
||||
{
|
||||
|
||||
ISW *caseinf;
|
||||
|
||||
int numcase=0,reg=AX,mode=0;
|
||||
|
||||
unsigned int endsw,defaul=0,tokr,endsw2=0;
|
||||
|
||||
int shortjmp=(tok==tk_switch?FALSE:TRUE);
|
||||
|
||||
int sline=linenumber;
|
||||
|
||||
REGISTERSTAT *bakregstat,*changeregstat;
|
||||
|
||||
char *ofsstr=NULL;
|
||||
|
||||
//new
|
||||
|
||||
COM_MOD *startmod=cur_mod;
|
||||
|
||||
unsigned char oinline=useinline;
|
||||
|
||||
#ifdef OPTVARCONST
|
||||
|
||||
ITOK otok;
|
||||
|
||||
int swvar=FALSE;
|
||||
|
||||
unsigned long numbervar;
|
||||
|
||||
int numrm;
|
||||
|
||||
int nonum;
|
||||
|
||||
#endif
|
||||
|
||||
useinline=0;
|
||||
|
||||
caseinf=(ISW *)MALLOC(sizeof(ISW)*MAXCASE); //¡«®ª ¤«ï ¨ä® ® case
|
||||
|
||||
numexpandcase=0;
|
||||
|
||||
uptdbr(/*TRUE*/);
|
||||
|
||||
getoperand();
|
||||
|
||||
char signflag=0;
|
||||
|
||||
expecting(tk_openbracket);
|
||||
|
||||
switch(tok){
|
||||
|
||||
case tk_intvar:
|
||||
|
||||
signflag=1;
|
||||
|
||||
goto dint;
|
||||
|
||||
case tk_int:
|
||||
|
||||
signflag=1;
|
||||
|
||||
case tk_word:
|
||||
|
||||
getoperand();
|
||||
|
||||
case tk_wordvar:
|
||||
|
||||
case tk_reg:
|
||||
|
||||
dint:
|
||||
|
||||
tokr=r16;
|
||||
|
||||
break;
|
||||
|
||||
case tk_charvar:
|
||||
|
||||
signflag=1;
|
||||
|
||||
goto dchar;
|
||||
|
||||
case tk_char:
|
||||
|
||||
signflag=1;
|
||||
|
||||
case tk_byte:
|
||||
|
||||
getoperand();
|
||||
|
||||
case tk_bytevar:
|
||||
|
||||
case tk_beg:
|
||||
|
||||
dchar:
|
||||
|
||||
tokr=r8;
|
||||
|
||||
break;
|
||||
|
||||
case tk_long:
|
||||
|
||||
signflag=1;
|
||||
|
||||
case tk_dword:
|
||||
|
||||
getoperand();
|
||||
|
||||
goto dlong;
|
||||
|
||||
case tk_qword:
|
||||
|
||||
getoperand();
|
||||
|
||||
goto qword;
|
||||
|
||||
case tk_floatvar:
|
||||
|
||||
case tk_longvar: signflag=1;
|
||||
|
||||
case tk_dwordvar:
|
||||
|
||||
case tk_reg32:
|
||||
|
||||
dlong:
|
||||
|
||||
tokr=r32;
|
||||
|
||||
break;
|
||||
|
||||
case tk_doublevar: signflag=1;
|
||||
|
||||
case tk_qwordvar:
|
||||
|
||||
qword:
|
||||
|
||||
tokr=r64;
|
||||
|
||||
break;
|
||||
|
||||
case tk_openbracket:
|
||||
|
||||
nexttok();
|
||||
|
||||
if(tok>=tk_char&&tok<=tk_double){
|
||||
|
||||
tokr=typesize(tok);
|
||||
|
||||
switch(tok){
|
||||
|
||||
case tk_double:
|
||||
|
||||
case tk_float:
|
||||
|
||||
case tk_char:
|
||||
|
||||
case tk_int:
|
||||
|
||||
case tk_long:
|
||||
|
||||
signflag=1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nexttok();
|
||||
|
||||
expectingoperand(tk_closebracket);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
tokr=(am32+1)*2;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
#ifdef OPTVARCONST
|
||||
|
||||
if(tok>=tk_charvar&&tok<=tk_dwordvar&&tok2==tk_closebracket){
|
||||
|
||||
otok=itok;
|
||||
|
||||
swvar=TRUE;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(ScanSwitch(&numcase,caseinf,startmod)){
|
||||
|
||||
int i;
|
||||
|
||||
unsigned int sizetab; //à §¬¥à â ¡«¨æë
|
||||
|
||||
unsigned long min=0xffffffff,max=0;
|
||||
|
||||
unsigned int size0=0,size1;
|
||||
|
||||
int reg0=0,svop=0;
|
||||
|
||||
long smin=0x7fffffff,smax=-0x7fffffff;
|
||||
|
||||
unsigned int size2=0;
|
||||
|
||||
unsigned oaddESP=addESP;
|
||||
|
||||
if(numcase>2){
|
||||
|
||||
if(!optimizespeed){
|
||||
|
||||
if((am32==FALSE&&tokr==r32)||(am32&&tokr==r16))size0=numcase;
|
||||
|
||||
else if(tokr==r8)size0=numcase*2;
|
||||
|
||||
if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket)
|
||||
|
||||
reg0=itok.number; //¯à¥¤¯®« £ ¥¬ë© ॣ¨áâà ¬¥â®¤ 0
|
||||
|
||||
}
|
||||
|
||||
for(i=0;i<numcase;i++){ //à áç¥â à §¬¥à ¯® ¬¥â®¤ã 0
|
||||
|
||||
if((caseinf+i)->value>max)max=(caseinf+i)->value;
|
||||
|
||||
if((caseinf+i)->value<min)min=(caseinf+i)->value;
|
||||
|
||||
if((long) (caseinf+i)->value>smax)smax=(caseinf+i)->value;
|
||||
|
||||
if((long) (caseinf+i)->value<smin)smin=(caseinf+i)->value;
|
||||
|
||||
if((!optimizespeed)&&tokr!=r8){
|
||||
|
||||
if((caseinf+i)->value==0)size0+=2;
|
||||
|
||||
else if((caseinf+i)->value<128)size0+=3;
|
||||
|
||||
else{
|
||||
|
||||
size0+=(reg0==0?3:4);
|
||||
|
||||
if(am32)size0+=2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(i!=0){
|
||||
|
||||
if((caseinf+i)->postcase==0)size0+=(am32==FALSE?(chip<3?5:4):6);
|
||||
|
||||
else size0+=2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((unsigned int)(smax-smin)<(max-min)){
|
||||
|
||||
max=smax-smin;
|
||||
|
||||
svop=8;
|
||||
|
||||
min=-smin;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
smin=min;
|
||||
|
||||
max-=min;
|
||||
|
||||
}
|
||||
|
||||
sizetab=max+1; //à §¬¥à â ¡«¨æë ¤«ï ¬¥â®¤ 1
|
||||
|
||||
if(sizetab<0x1000000&&(!(am32==FALSE&&tokr==r32))){
|
||||
|
||||
if(optimizespeed){
|
||||
|
||||
if((unsigned int)(sizetab/numcase)<(unsigned int)(am32==FALSE?3:4)){
|
||||
|
||||
mode=1;
|
||||
|
||||
if(am32==FALSE)reg=BX;
|
||||
|
||||
/* ¥á«¨ ®â®è¥¨¥ ç¨á« í«¥¬¥â®¢ ¢ â ¡«¨æ¥ ª ç¨á«ã case ¬¥¥¥
|
||||
|
||||
3 ¤«ï 16-¡¨â®£® ०¨¬ ¨ 4 ¤«ï 32-¡¨â®£®, â® ¡¥à¥âáï ¬¥â®¤ 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{ //¢ëç¨á«¨âì à §¬¥à ¤«ï ®¯â¨¬¨§ 樨 ¯® à §¬¥àã
|
||||
|
||||
if(shortjmp)size0+=2;
|
||||
|
||||
else size0+=(am32==FALSE?(chip<3?5:4):6);
|
||||
|
||||
size1=sizetab*(am32==FALSE?2:4);
|
||||
|
||||
size1+=(max<128?3:am32==FALSE?4:6)+(shortjmp==FALSE?(chip<3?5:4):2);
|
||||
|
||||
if(max>127&®0==AX)size1--;
|
||||
|
||||
if(min!=0){
|
||||
|
||||
if(min==1)size1++;
|
||||
|
||||
else if(min==2&&(!optimizespeed))size1+=2;
|
||||
|
||||
else if(min<128)size1+=3;
|
||||
|
||||
else{
|
||||
|
||||
size1+=(am32==FALSE?4:6);
|
||||
|
||||
if(reg0==AX)size1--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size1+=(am32==FALSE?6:9);
|
||||
|
||||
if(am32){
|
||||
|
||||
if(tokr!=r32)size1+=3;
|
||||
|
||||
if(shortjmp)size1-=2;
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(reg0!=BX)size1+=2;
|
||||
|
||||
}
|
||||
|
||||
//¢ë¡®à ¬¥â®¤ á ¬¥ì訬 à §¬¥à®¬
|
||||
|
||||
if(size1<=size0){
|
||||
|
||||
mode=1;
|
||||
|
||||
size0=size1;
|
||||
|
||||
if(am32==FALSE)reg=BX;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(numcase>9&&(!optimizespeed)){
|
||||
|
||||
// à áç¥â ¬¥â®¤ 2
|
||||
|
||||
size2=numcase+numexpandcase;
|
||||
|
||||
switch(tokr){
|
||||
|
||||
case r8:
|
||||
|
||||
if(am32)size2=size2*5;
|
||||
|
||||
else size2=size2*3+8;
|
||||
|
||||
break;
|
||||
|
||||
case r16:
|
||||
|
||||
if(am32)size2=size2*6+1;
|
||||
|
||||
else size2=size2*4+8;
|
||||
|
||||
break;
|
||||
|
||||
case r32:
|
||||
|
||||
if(am32)size2=size2*8;
|
||||
|
||||
else size2=size2*6+9;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
size2+=29;
|
||||
|
||||
//¢ë¡®à ¬¥â®¤ á ¬¥ì訬 à §¬¥à®¬
|
||||
|
||||
if(size2<=size0)mode=2;
|
||||
|
||||
}
|
||||
|
||||
// printf("Num CASE %d Metod 0 size=%d. Metod 1 size=%d. Metod 2 size=%d\n",numcase,size0,size1,size2);
|
||||
|
||||
if(mode==2){
|
||||
|
||||
reg=AX;
|
||||
|
||||
reg0=idxregs[1];
|
||||
|
||||
if((!am32)||(am32&&(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket)))){
|
||||
|
||||
if(tokr==r8)doalmath(signflag,&ofsstr);
|
||||
|
||||
else do_e_axmath(signflag,tokr,&ofsstr);
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
reg=itok.number;
|
||||
|
||||
if(reg==reg0)reg0=idxregs[0];
|
||||
|
||||
nexttok();
|
||||
|
||||
}
|
||||
|
||||
ClearReg(reg);
|
||||
|
||||
ClearReg(reg0);
|
||||
|
||||
warningreg(regs[am32][reg0]);
|
||||
Reference in New Issue
Block a user