#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&&reg0==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]);

		}

		else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket){

			if(reg==AX){

				reg=itok.number;

				if(mode&&am32)getintoreg_32(reg,r32,0,&ofsstr);

				else nexttok();

				ClearReg(AX);

			}

			else{

				getintoreg_32(BX,r16,0,&ofsstr);

				ClearReg(BX);

				warningreg("BX");

			}

		}

		else{

			if(tokr==r8)doalmath(signflag,&ofsstr);

			else do_e_axmath(signflag,tokr,&ofsstr);

			if(reg!=AX){

				ClearReg(BX);

				if(tokr==r8)outword(0xB4);	//mov ah,0

				if(optimizespeed)outword(0xC389);	//mov bx,ax

				else op(0x93);	//xchg ax,bx

			}

			else{

				ClearReg(AX);

				if(mode&&am32&&tokr!=r32){

					op(0x0F);

					op(tokr==r8?0xB6:0xB7);

					op(0xC0);

				}

			}

		}

		nextexpecting2(tk_openbrace);	//¯à®¢ ­  ®âªà ᪮¡ªã

		if(numcase){

			if(mode==1){	//¯¥à¢ë© ¬¥â®¤

				if(min!=0){

					if(min==1)op(0x48+reg-svop);	//dec reg

					else if(min==2&&(!optimizespeed)){

						op(0x48+reg-svop);	//dec reg

						op(0x48+reg-svop);	//dec reg

					}

					else if(min<128){

						op(0x83);

						op(0xE8+reg-svop*5);

						op(min);

					}

					else{

						if(reg==AX)op(0x2D-svop*5);

						else{

							op(0x81);

							op(0xE8+reg-svop*5);

						}

						if(am32)outdword(min);

						else outword(min);

					}

					if(am32)warningreg(regs[1][reg]);

				}

				if(max<128){

					op(0x83);	//cmp reg,max

					op(0xF8+reg);

					op(max);

				}

				else{

					if(reg==AX)op(0x3D);

					else{

						op(0x81);

						op(0xF8+reg);

					}

					if(am32)outdword(max);

					else outword(max);

				}

				if(shortjmp==FALSE){

					if(chip<3){

						outword(0x376);	//jbe 3

						op(0xE9);	//jmp to default

					}

					else outword(0x870F);	//ja default

					outword(0);

					if(am32)outword(0);

				}

				else{

					op(0x77);

					op(0);

				}

				endsw=outptr;	// ¤à¥á ª®­æ  switch ¨«¨ default

				if(am32){

					outword(0x24FF);

					op(0x85+reg*8);

				}

				else outdword(0xA7FFDB01);	//add bx,bx jmp [bx+table]

				AddReloc(CS);

				size1=outptr;

				outword(0);

				if(am32)outword(0);

			}

			else if(mode==0){

				svop=numcase;

				for(;numcase>0;){	//¢¥â¢«¥­¨¥

					numcase--;

					CmpRegNum(tokr,(caseinf+numcase)->value,reg);

					if((caseinf+numcase)->type==singlcase){

						if(numcase){

							if((caseinf+numcase)->postcase==FALSE){

								if(chip<3){

									outword(0x375);	//jnz 3

									op(0xE9);	//jmp to default

								}

								else outword(0x840F);	//jz default

								outword(0);

								if(am32)outword(0);

							}

							else outword(0x74);

							(caseinf+numcase)->postcase=outptr;

						}

						else{

							if(shortjmp==FALSE){

								if(chip<3){

									outword(0x374);	//jnz 3

									op(0xE9);	//jmp to default

								}

								else outword(0x850F);	//jz default

								outword(0);

								if(am32)outword(0);

							}

							else outword(0x75);

							endsw=outptr;	// ¤à¥á ª®­æ  switch ¨«¨ default

						}

					}

					else{	//case 1...5

						numcase--;

						max=(caseinf+numcase)->value;

						if(numcase!=0){

							if((caseinf+numcase+1)->postcase==FALSE){

								if(max==0){

									if(chip>2){

										outdword(0x860F);

										if(am32)outword(0);

									}

									else{

										outword(am32==FALSE?0x0377:0x577);

										jumploc0();

									}

								}

								else{

									outword(0x77);

									endsw=outptr;

									CmpRegNum(tokr,max,reg);

									if(chip>2){

										outdword(0x830F);

										if(am32)outword(0);

									}

									else{

										outword(am32==FALSE?0x0372:0x572);

										jumploc0();

									}

									output[endsw-1]=(unsigned char)(outptr-endsw);

								}

							}

							else{

								if(max==0)outword(0x76);

								else{

									outword(0x77);

									endsw=outptr;

									CmpRegNum(tokr,max,reg);

									outword(0x73);

									output[endsw-1]=(unsigned char)(outptr-endsw);

								}

							}

							(caseinf+numcase)->postcase=outptr;

						}

						else{

							if(shortjmp==FALSE){

								if((optimizespeed&&chip>2)||(chip>2&&max==0)){

									outdword(0x870F);

									if(am32)outword(0);

									if(max!=0){

										endsw2=outptr;

										CmpRegNum(tokr,max,reg);

										outdword(0x820F);

										if(am32)outword(0);

									}

								}

								else{

									if(max==0) outword(am32==FALSE?0x0376:0x576);

									else{

										outword(0x77);

										endsw=outptr-1;

										CmpRegNum(tokr,max,reg);

										outword(am32==FALSE?0x0373:0x573);

										output[endsw]=(unsigned char)(outptr-endsw-1);

									}

									jumploc0();

								}

							}

							else{

								outword(0x77);

								if(max!=0){

									endsw2=outptr;

									CmpRegNum(tokr,max,reg);

									outword(0x72);

								}

							}

							endsw=outptr;	// ¤à¥á ª®­æ  switch ¨«¨ default

						}

					}

				}

			}

			else if(mode==2){

				if(!am32){

					outdword(0x071E0651);	//push cx,es,ds pop es

					op(0xB9);	//mov CX,numcase

					outword(numcase+numexpandcase);

					op(0xBF);	//mov DI,tableval

					AddReloc(CS);

					size2=outptr;

					outword(0);

					op(0xF2);	//repnz

					switch(tokr){

						case r8: op(0xAE); break;

						case r32: op(0x66);

						case r16: op(0xAF); break;

					}

					outword(0x7407);	//pop es ,jz

					op(shortjmp==FALSE?4:3);

					op(0x59);	//pop cx

					if(shortjmp==FALSE)jumploc0();

					else outword(0xEB);

					endsw=outptr;	// ¤à¥á ª®­æ  switch ¨«¨ default

					op(0xBF);	//mov DI,numcase

					outword(numcase+numexpandcase);

					outdword(0x014FCF29);	//sub di,cx dec di add di,di

					op(0xFF);

					outword(0xC781);	//add di,tableadr

					AddReloc(CS);

					size1=outptr;

					outword(0);

					op(0x59);	//pop cx

					outword(0x25FF);	//jmp [di]

				}

				else{

					op(0x31);

					op(0xC0+reg0*9);	//xor reg0,reg0

					switch(tokr){	//cmp [reg0*size+tableadr],reg

						case r8: op(0x38); op(0x4+reg*8); op(5+reg0*8); break;

						case r32: op(0x39); op(0x4+reg*8); op(0x85+reg0*8); break;

						case r16: op(0x66); op(0x39); op(0x4+reg*8); op(0x45+reg0*8); break;

					}

					AddReloc(CS);

					size2=outptr;

					outdword(0);

					outword(0x0775);	//jne

					outword(0x24FF);	//jmp [reg0*4+tableadr]

					op(0x85+reg0*8);

					AddReloc(CS);

					size1=outptr;

					outdword(0);

					op(0x40+reg0);	//inc reg0

					if((numcase+numexpandcase)>127){	//cmp reg0,numcase

						op(0x81);

						op(0xF8+reg0);

						outdword(numcase+numexpandcase);

					}

					else{

						op(0x83);

						op(0xF8+reg0);

						op(numcase+numexpandcase);

					}

					op(0x72);

					if((numcase+numexpandcase)>127)op(tokr==r16?0xE6:0xE7);

					else op(tokr==r16?0xE9:0xEA);

					if(shortjmp==FALSE)jumploc0();

					else outword(0xEB);

					endsw=outptr;	// ¤à¥á ª®­æ  switch ¨«¨ default

				}

			}

		}

		numcase=0;

		useinline=oinline;

		bakregstat=BakRegStat();

		changeregstat=BakRegStat();

		lastcommand=tk_switch;

		do{

			if(tok==tk_case||tok==tk_CASE||tok==tk_default){     //¥á«¨ case - § ¯®¬­¨âì ¯®§¨æ¨î ¨ ¢¥«¨ç¨­ã

				RestoreStack();

				CompareRegStat(changeregstat);

				switch(lastcommand){

					case tk_goto:

					case tk_GOTO:

					case tk_break:

					case tk_BREAK:

					case tk_return:

					case tk_RETURN:

					case tk_switch:

						CopyRegStat(bakregstat);

#ifdef OPTVARCONST

						nonum=FALSE;

#endif

						addESP=oaddESP;

						break;

					default:

						CopyRegStat(changeregstat);

#ifdef OPTVARCONST

						nonum=TRUE;

#endif

						if(ESPloc&&am32&&oaddESP!=addESP)warESP();

						break;

				}

				if(tok==tk_default){	//⮦¥ ¤«ï default

					if(mode==0&&svop){

						if(numcase==0)jumploc0();	//default á ¬ë© ¯¥à¢ë©

						CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);

						if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);

					}

					if(defaul)preerror("Duplicate 'default'");

					defaul=outptr;

					nexttok();

					expecting(tk_colon);	//¯à®¢ ­  : ¨ ç⥭¨¥ á«¥¤ãîé tok

					continue;

				}

				if(mode==0){

					if(numcase==0&&defaul){	//default á ¬ë© ¯¥à¢ë©

						if(am32==FALSE)*(unsigned short *)&output[defaul-2]=(unsigned short)(outptr-defaul);

						else *(unsigned long *)&output[defaul-4]=(unsigned long)(outptr-defaul);

					}

					else if(numcase)CheckJmpSW(linenumber,(caseinf+numcase)->postcase,outptr,tok==tk_case?FALSE:TRUE,mesCASE);

				}

				else (caseinf+numcase)->postcase=outptr;

				lastcommand=tok;	//new 12.12.07 14:27

				nexttok();

#ifdef OPTVARCONST

				numrm=itok.rm;

				numbervar=doconstlongmath();

				(caseinf+numcase)->value=numbervar-(mode==1?smin:0);

#else

				(caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0);

#endif

				numcase++;

				if(tok==tk_multipoint){

					nexttok();

					(caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0);

					numcase++;

				}

#ifdef OPTVARCONST

				else if(swvar&&nonum==FALSE)Const2Var(&otok,numbervar,numrm);

#endif

				expecting(tk_colon);	//¯à®¢ ­  : ¨ ç⥭¨¥ á«¥¤ãîé tok

				if(tok==tk_closebrace)numcase--;

				continue;//goto checkcase;

			}

			startblock();

			docommand();

			endblock();

		}while(tok!=tk_closebrace);

		RestoreStack();

		if(numberbreak==0){

			switch(lastcommand){

				case tk_break:

					posts--;

					outptr-=(am32==FALSE?3:5);

					break;

				case tk_BREAK:

					posts--;

					outptr-=2;

					break;

			}

		}

		if(defaul&&outptr<defaul){

			if(mode==0&&svop){

				if(numcase==0)jumploc0();	//default á ¬ë© ¯¥à¢ë©

				CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);

				if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);

			}

			defaul=outptr;

		}

//		printf("outptr=%08X defaul=%08X\n",outptr,defaul);

		CompareRegStat(changeregstat);

		FreeStat(bakregstat);

		CopyRegStat(changeregstat);

		FreeStat(changeregstat);

		if(numcase){

			if(mode==0){

				if(defaul==0){

					CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);

					if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);

				}

				free(caseinf);

			}

			else{

				if(defaul==0||defaul>outptr)defaul=outptr;

				CheckJmpSW(sline,endsw,defaul,shortjmp,mesSWITCH);

				caseinf=(ISW *)REALLOC(caseinf,sizeof(ISW)*numcase);

				if(!numswtable)swtables=(FSWI *)MALLOC(sizeof(FSWI));

				else swtables=(FSWI *)REALLOC(swtables,sizeof(FSWI)*(numswtable+1));

				FSWI *swt=swtables+numswtable;

				swt->info=caseinf;

				swt->sizetab=(mode==2?numcase:sizetab)+numexpandcase;

				swt->type=(am32==FALSE?2:4);

				swt->numcase=numcase;

				swt->defal=defaul;

				swt->ptb=size1;

				swt->ptv=size2;

				swt->mode=mode;

				swt->razr=tokr;

				numswtable++;

			}

		}

		else free(caseinf);

		SetBreakLabel();

		SetContinueLabel();

	}

	nexttok();

	lastcommand=tk_switch;

	retproc=FALSE;

}