Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #define _SWITCH_
  2.  
  3.  
  4.  
  5. #include "tok.h"
  6.  
  7.  
  8.  
  9. extern int lastcommand; //¯®á«¥¤­¨© ®¯¥à â®à ¢ ¡«®ª¥
  10.  
  11.  
  12.  
  13. #define MAXCASE 1024
  14.  
  15.  
  16.  
  17. FSWI *swtables; //â ¡«¨æ  ¨­ä®à¬ æ¨© ®¡ switch
  18.  
  19. int numswtable=0;       //ç¨á«® ¡«®ª®¢ ¢ í⮩ â ¡«¨æ¥
  20.  
  21. char mesSWITCH[]="SWITCH";
  22.  
  23. char mesCASE[]="CASE";
  24.  
  25. int numexpandcase;
  26.  
  27. int numberbreak=0;
  28.  
  29.  
  30.  
  31. void CheckJmpSW(int line,int endsw,int startsw,int shortjmp,char *mes)
  32.  
  33. {
  34.  
  35. int size=startsw-endsw;
  36.  
  37.         if(shortjmp==FALSE){
  38.  
  39.                 if((unsigned int)size<128)warningjmp(mes,line);
  40.  
  41.                 if(am32==FALSE)*(unsigned short *)&output[endsw-2]=(unsigned short)size;
  42.  
  43.                 else *(unsigned long *)&output[endsw-4]=(unsigned long)size;
  44.  
  45.         }
  46.  
  47.         else{
  48.  
  49.                 if((unsigned int)size>127)jumperror(line,mes);
  50.  
  51.                 output[endsw-1]=(unsigned char) size;
  52.  
  53.         }
  54.  
  55. }
  56.  
  57.  
  58.  
  59. void CmpRegNum(int tokr,unsigned long value,int reg)
  60.  
  61. {
  62.  
  63.         if(tokr!=r8){
  64.  
  65.                 op66(tokr);         //CMP EAX,val
  66.  
  67.                 if(value==0){
  68.  
  69.                         op(0x85);
  70.  
  71.                         op(0xC0+reg*9); //test AX,AX
  72.  
  73.                 }
  74.  
  75.                 else{
  76.  
  77.                         if(short_ok(value,tokr==r32?TRUE:FALSE)){
  78.  
  79.                                 op(0x83);
  80.  
  81.                                 op(0xF8+reg);
  82.  
  83.                                 op(value);
  84.  
  85.                         }
  86.  
  87.                         else{
  88.  
  89.                                 if(reg==0)op(0x3D);
  90.  
  91.                                 else{
  92.  
  93.                                         op(0x81);
  94.  
  95.                                         op(0xF8+reg);
  96.  
  97.                                 }
  98.  
  99.                                 tokr==r32?outdword(value):outword(value);
  100.  
  101.                         }
  102.  
  103.                 }
  104.  
  105.         }
  106.  
  107.         else{                   //CMP AL,val
  108.  
  109.                 if(value==0){
  110.  
  111.                         op(0x84);
  112.  
  113.                         op(0xC0+reg*9);
  114.  
  115.                 }
  116.  
  117.                 else{
  118.  
  119.                         if(reg==0)op(0x3c);
  120.  
  121.                         else{
  122.  
  123.                                 op(0x80);
  124.  
  125.                                 op(0xF8+reg);
  126.  
  127.                         }
  128.  
  129.                         op(value);
  130.  
  131.                 }
  132.  
  133.         }
  134.  
  135. }
  136.  
  137.  
  138.  
  139. int ScanSwitch(int *numcase,ISW *caseinf,COM_MOD *startmod)
  140.  
  141. {
  142.  
  143. unsigned char dcha;
  144.  
  145. int dtok,line,oinptr,i,otok2;
  146.  
  147. //new
  148.  
  149. unsigned char *oinput;
  150.  
  151. int oendinptr;
  152.  
  153.  
  154.  
  155. ITOK otok;
  156.  
  157. int retcode=TRUE;
  158.  
  159.         dtok=tok;
  160.  
  161.         otok=itok;
  162.  
  163.         otok2=tok2;
  164.  
  165.         line=linenum2;
  166.  
  167.         dcha=cha2;
  168.  
  169.         oinptr=inptr=inptr2;
  170.  
  171.         cha=cha2;
  172.  
  173. //new
  174.  
  175.         oinput=input;
  176.  
  177.         oendinptr=endinptr;
  178.  
  179.         if(startmod!=cur_mod){
  180.  
  181.                 COM_MOD *pmod=cur_mod;
  182.  
  183.                 while(pmod->next!=startmod){
  184.  
  185.                         pmod=pmod->next;
  186.  
  187.                 }
  188.  
  189.                 input=pmod->input;
  190.  
  191.                 inptr=pmod->inptr;
  192.  
  193.                 endinptr=pmod->endinptr;
  194.  
  195.                 cha=input[inptr];
  196.  
  197.                 inptr++;
  198.  
  199.         }
  200.  
  201.  
  202.  
  203.         if(SkipParam()){
  204.  
  205.                 FastTok(0);
  206.  
  207.                 if(tok!=tk_openbrace){
  208.  
  209.                         SwTok(tk_openbrace);
  210.  
  211.                         retcode=FALSE;
  212.  
  213.                 }
  214.  
  215.                 else{
  216.  
  217.                         for(i=1;i!=0;){
  218.  
  219.                                 FastTok(1);
  220.  
  221.                                 if(tok==tk_question)CheckDir();
  222.  
  223.                                 switch(tok){
  224.  
  225.                                         case tk_eof:
  226.  
  227.                                                 unexpectedeof();
  228.  
  229.                                                 retcode=FALSE;
  230.  
  231.                                                 i=0;
  232.  
  233.                                                 break;
  234.  
  235.                                         case tk_openbrace: i++; break;
  236.  
  237.                                         case tk_closebrace: i--; break;
  238.  
  239.                                         case tk_id:
  240.  
  241.                                         case tk_case:
  242.  
  243.                                         case tk_CASE:
  244.  
  245.                                                 if(i==1){
  246.  
  247.                                                         if(stricmp(itok.name,"case")==0){
  248.  
  249.                                                                 inptr2=inptr;
  250.  
  251.                                                                 cha2=cha;
  252.  
  253.                                                                 linenum2=linenumber;
  254.  
  255.                                                                 (caseinf+*numcase)->postcase=(itok.name[0]=='c'?FALSE:TRUE);
  256.  
  257.                                                                 nexttok();
  258.  
  259.                                                                 if(tok==tk_number||(tok==tk_minus&&tok2==tk_number)){
  260.  
  261.                                                                         if(*numcase==MAXCASE){
  262.  
  263.                                                                                 preerror("Many to use <case>");
  264.  
  265.                                                                                 retcode=FALSE;
  266.  
  267.                                                                         }
  268.  
  269.                                                                         else{
  270.  
  271.                                                                                 unsigned long val=doconstlongmath();
  272.  
  273.                                                                                 for(int j=0;j<*numcase;j++){
  274.  
  275.                                                                                         if(val==(caseinf+j)->value){
  276.  
  277.                                                                                                 preerror("Duplicate 'case'");
  278.  
  279.                                                                                                 retcode=FALSE;
  280.  
  281.                                                                                                 break;
  282.  
  283.                                                                                         }
  284.  
  285.                                                                                 }
  286.  
  287.                                                                                 (caseinf+*numcase)->value=val;
  288.  
  289.                                                                                 if(tok==tk_multipoint){
  290.  
  291.                                                                                         (caseinf+*numcase)->type=startmulti;
  292.  
  293.                                                                                         nexttok();
  294.  
  295.                                                                                         val=doconstlongmath();
  296.  
  297.                                                                                         numexpandcase+=val-(caseinf+*numcase)->value-1;
  298.  
  299.                                                                                         if(val<(caseinf+*numcase)->value){
  300.  
  301.                                                                                                 preerror("The first value 'case' should be smaller");
  302.  
  303.                                                                                                 retcode=FALSE;
  304.  
  305.                                                                                         }
  306.  
  307.                                                                                         *numcase=*numcase+1;
  308.  
  309.                                                                                         (caseinf+*numcase)->type=endmulti;
  310.  
  311.                                                                                         (caseinf+*numcase)->value=val;
  312.  
  313.                                                                                         (caseinf+*numcase)->postcase=(caseinf+*numcase-1)->postcase;
  314.  
  315.                                                                                 }
  316.  
  317.                                                                                 else (caseinf+*numcase)->type=singlcase;
  318.  
  319.                                                                                 *numcase=*numcase+1;
  320.  
  321.                                                                         }
  322.  
  323.                                                                 }
  324.  
  325.                                                                 else{
  326.  
  327.                                                                         numexpected();
  328.  
  329.                                                                         retcode=FALSE;
  330.  
  331.                                                                 }
  332.  
  333.                                                                 inptr=inptr2;
  334.  
  335.                                                                 cha=cha2;
  336.  
  337.                                                         }
  338.  
  339.                                                 }
  340.  
  341.                                                 break;
  342.  
  343.                                 }
  344.  
  345.                         }
  346.  
  347.                 }
  348.  
  349.         }
  350.  
  351.         if(retcode){    //¥á«¨ ­¥ ­ ©¤¥­® ®è¨¡®ª
  352.  
  353.                 tok=dtok;
  354.  
  355.                 itok=otok;
  356.  
  357.                 linenum2=line;
  358.  
  359.                 cha2=dcha;
  360.  
  361.                 inptr2=oinptr;
  362.  
  363.                 tok2=otok2;
  364.  
  365.         }
  366.  
  367.         else{
  368.  
  369.                 inptr2=inptr;
  370.  
  371.                 cha2=cha;
  372.  
  373.                 linenum2=linenumber;
  374.  
  375.         }
  376.  
  377. //new
  378.  
  379.         input=oinput;
  380.  
  381.         endinptr=oendinptr;
  382.  
  383.  
  384.  
  385.         return retcode;
  386.  
  387. }
  388.  
  389.  
  390.  
  391. void doswitch()
  392.  
  393. {
  394.  
  395. ISW *caseinf;
  396.  
  397. int numcase=0,reg=AX,mode=0;
  398.  
  399. unsigned int endsw,defaul=0,tokr,endsw2=0;
  400.  
  401. int shortjmp=(tok==tk_switch?FALSE:TRUE);
  402.  
  403. int sline=linenumber;
  404.  
  405. REGISTERSTAT *bakregstat,*changeregstat;
  406.  
  407. char *ofsstr=NULL;
  408.  
  409. //new
  410.  
  411. COM_MOD *startmod=cur_mod;
  412.  
  413. unsigned char oinline=useinline;
  414.  
  415. #ifdef OPTVARCONST
  416.  
  417. ITOK otok;
  418.  
  419. int swvar=FALSE;
  420.  
  421. unsigned long numbervar;
  422.  
  423. int numrm;
  424.  
  425. int nonum;
  426.  
  427. #endif
  428.  
  429.         useinline=0;
  430.  
  431.         caseinf=(ISW *)MALLOC(sizeof(ISW)*MAXCASE);     //¡«®ª ¤«ï ¨­ä® ® case
  432.  
  433.         numexpandcase=0;
  434.  
  435.         uptdbr(/*TRUE*/);
  436.  
  437.         getoperand();
  438.  
  439. char signflag=0;
  440.  
  441.         expecting(tk_openbracket);
  442.  
  443.         switch(tok){
  444.  
  445.                 case tk_intvar:
  446.  
  447.                         signflag=1;
  448.  
  449.                         goto dint;
  450.  
  451.                 case tk_int:
  452.  
  453.                         signflag=1;
  454.  
  455.                 case tk_word:
  456.  
  457.                         getoperand();
  458.  
  459.                 case tk_wordvar:
  460.  
  461.                 case tk_reg:
  462.  
  463. dint:
  464.  
  465.                         tokr=r16;
  466.  
  467.                         break;
  468.  
  469.                 case tk_charvar:
  470.  
  471.                         signflag=1;
  472.  
  473.                         goto dchar;
  474.  
  475.                 case tk_char:
  476.  
  477.                         signflag=1;
  478.  
  479.                 case tk_byte:
  480.  
  481.                         getoperand();
  482.  
  483.                 case tk_bytevar:
  484.  
  485.                 case tk_beg:
  486.  
  487. dchar:
  488.  
  489.                         tokr=r8;
  490.  
  491.                         break;
  492.  
  493.                 case tk_long:
  494.  
  495.                         signflag=1;
  496.  
  497.                 case tk_dword:
  498.  
  499.                         getoperand();
  500.  
  501.                         goto dlong;
  502.  
  503.                 case tk_qword:
  504.  
  505.                         getoperand();
  506.  
  507.                         goto qword;
  508.  
  509.                 case tk_floatvar:
  510.  
  511.                 case tk_longvar: signflag=1;
  512.  
  513.                 case tk_dwordvar:
  514.  
  515.                 case tk_reg32:
  516.  
  517. dlong:
  518.  
  519.                         tokr=r32;
  520.  
  521.                         break;
  522.  
  523.                 case tk_doublevar: signflag=1;
  524.  
  525.                 case tk_qwordvar:
  526.  
  527. qword:
  528.  
  529.                         tokr=r64;
  530.  
  531.                         break;
  532.  
  533.                 case tk_openbracket:
  534.  
  535.                         nexttok();
  536.  
  537.                         if(tok>=tk_char&&tok<=tk_double){
  538.  
  539.                                 tokr=typesize(tok);
  540.  
  541.                                 switch(tok){
  542.  
  543.                                         case tk_double:
  544.  
  545.                                         case tk_float:
  546.  
  547.                                         case tk_char:
  548.  
  549.                                         case tk_int:
  550.  
  551.                                         case tk_long:
  552.  
  553.                                                 signflag=1;
  554.  
  555.                                 }
  556.  
  557.                         }
  558.  
  559.                         nexttok();
  560.  
  561.                         expectingoperand(tk_closebracket);
  562.  
  563.                         break;
  564.  
  565.                 default:
  566.  
  567.                         tokr=(am32+1)*2;
  568.  
  569.                         break;
  570.  
  571.         }
  572.  
  573. #ifdef OPTVARCONST
  574.  
  575.         if(tok>=tk_charvar&&tok<=tk_dwordvar&&tok2==tk_closebracket){
  576.  
  577.                 otok=itok;
  578.  
  579.                 swvar=TRUE;
  580.  
  581.         }
  582.  
  583. #endif
  584.  
  585.         if(ScanSwitch(&numcase,caseinf,startmod)){
  586.  
  587. int i;
  588.  
  589. unsigned int sizetab;   //à §¬¥à â ¡«¨æë
  590.  
  591. unsigned long min=0xffffffff,max=0;
  592.  
  593. unsigned int size0=0,size1;
  594.  
  595. int reg0=0,svop=0;
  596.  
  597. long smin=0x7fffffff,smax=-0x7fffffff;
  598.  
  599. unsigned int size2=0;
  600.  
  601. unsigned oaddESP=addESP;
  602.  
  603.                 if(numcase>2){
  604.  
  605.                         if(!optimizespeed){
  606.  
  607.                                 if((am32==FALSE&&tokr==r32)||(am32&&tokr==r16))size0=numcase;
  608.  
  609.                                 else if(tokr==r8)size0=numcase*2;
  610.  
  611.                                 if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket)
  612.  
  613.                                         reg0=itok.number;       //¯à¥¤¯®« £ ¥¬ë© ॣ¨áâà ¬¥â®¤  0
  614.  
  615.                         }
  616.  
  617.                         for(i=0;i<numcase;i++){ //à áç¥â à §¬¥à  ¯® ¬¥â®¤ã 0
  618.  
  619.                                 if((caseinf+i)->value>max)max=(caseinf+i)->value;
  620.  
  621.                                 if((caseinf+i)->value<min)min=(caseinf+i)->value;
  622.  
  623.                                 if((long) (caseinf+i)->value>smax)smax=(caseinf+i)->value;
  624.  
  625.                                 if((long) (caseinf+i)->value<smin)smin=(caseinf+i)->value;
  626.  
  627.                                 if((!optimizespeed)&&tokr!=r8){
  628.  
  629.                                         if((caseinf+i)->value==0)size0+=2;
  630.  
  631.                                         else if((caseinf+i)->value<128)size0+=3;
  632.  
  633.                                         else{
  634.  
  635.                                                 size0+=(reg0==0?3:4);
  636.  
  637.                                                 if(am32)size0+=2;
  638.  
  639.                                         }
  640.  
  641.                                 }
  642.  
  643.                                 if(i!=0){
  644.  
  645.                                         if((caseinf+i)->postcase==0)size0+=(am32==FALSE?(chip<3?5:4):6);
  646.  
  647.                                         else size0+=2;
  648.  
  649.                                 }
  650.  
  651.                         }
  652.  
  653.                         if((unsigned int)(smax-smin)<(max-min)){
  654.  
  655.                                 max=smax-smin;
  656.  
  657.                                 svop=8;
  658.  
  659.                                 min=-smin;
  660.  
  661.                         }
  662.  
  663.                         else{
  664.  
  665.                                 smin=min;
  666.  
  667.                                 max-=min;
  668.  
  669.                         }
  670.  
  671.                         sizetab=max+1;  //à §¬¥à â ¡«¨æë ¤«ï ¬¥â®¤  1
  672.  
  673.                         if(sizetab<0x1000000&&(!(am32==FALSE&&tokr==r32))){
  674.  
  675.                                 if(optimizespeed){
  676.  
  677.                                         if((unsigned int)(sizetab/numcase)<(unsigned int)(am32==FALSE?3:4)){
  678.  
  679.                                                 mode=1;
  680.  
  681.                                                 if(am32==FALSE)reg=BX;
  682.  
  683.                                         /* ¥á«¨ ®â­®è¥­¨¥ ç¨á«  í«¥¬¥­â®¢ ¢ â ¡«¨æ¥ ª ç¨á«ã case ¬¥­¥¥
  684.  
  685.                                          3 ¤«ï 16-¡¨â­®£® ०¨¬  ¨ 4 ¤«ï 32-¡¨â­®£®, â® ¡¥à¥âáï ¬¥â®¤ 1 */
  686.  
  687.                                         }
  688.  
  689.                                 }
  690.  
  691.                                 else{   //¢ëç¨á«¨âì à §¬¥à ¤«ï ®¯â¨¬¨§ æ¨¨ ¯® à §¬¥àã
  692.  
  693.                                         if(shortjmp)size0+=2;
  694.  
  695.                                         else size0+=(am32==FALSE?(chip<3?5:4):6);
  696.  
  697.                                         size1=sizetab*(am32==FALSE?2:4);
  698.  
  699.                                         size1+=(max<128?3:am32==FALSE?4:6)+(shortjmp==FALSE?(chip<3?5:4):2);
  700.  
  701.                                         if(max>127&&reg0==AX)size1--;
  702.  
  703.                                         if(min!=0){
  704.  
  705.                                                 if(min==1)size1++;
  706.  
  707.                                                 else if(min==2&&(!optimizespeed))size1+=2;
  708.  
  709.                                                 else if(min<128)size1+=3;
  710.  
  711.                                                 else{
  712.  
  713.                                                         size1+=(am32==FALSE?4:6);
  714.  
  715.                                                         if(reg0==AX)size1--;
  716.  
  717.                                                 }
  718.  
  719.                                         }
  720.  
  721.                                         size1+=(am32==FALSE?6:9);
  722.  
  723.                                         if(am32){
  724.  
  725.                                                 if(tokr!=r32)size1+=3;
  726.  
  727.                                                 if(shortjmp)size1-=2;
  728.  
  729.                                         }
  730.  
  731.                                         else{
  732.  
  733.                                                 if(reg0!=BX)size1+=2;
  734.  
  735.                                         }
  736.  
  737.                                 //¢ë¡®à ¬¥â®¤  á ¬¥­ì訬 à §¬¥à®¬
  738.  
  739.                                         if(size1<=size0){
  740.  
  741.                                                 mode=1;
  742.  
  743.                                                 size0=size1;
  744.  
  745.                                                 if(am32==FALSE)reg=BX;
  746.  
  747.  
  748.  
  749.                                         }
  750.  
  751.                                 }
  752.  
  753.                         }
  754.  
  755.                 }
  756.  
  757.                 if(numcase>9&&(!optimizespeed)){
  758.  
  759. // à áç¥â ¬¥â®¤  2
  760.  
  761.                         size2=numcase+numexpandcase;
  762.  
  763.                         switch(tokr){
  764.  
  765.                                 case r8:
  766.  
  767.                                         if(am32)size2=size2*5;
  768.  
  769.                                         else size2=size2*3+8;
  770.  
  771.                                         break;
  772.  
  773.                                 case r16:
  774.  
  775.                                         if(am32)size2=size2*6+1;
  776.  
  777.                                         else size2=size2*4+8;
  778.  
  779.                                         break;
  780.  
  781.                                 case r32:
  782.  
  783.                                         if(am32)size2=size2*8;
  784.  
  785.                                         else size2=size2*6+9;
  786.  
  787.                                         break;
  788.  
  789.                         }
  790.  
  791.                         size2+=29;
  792.  
  793.                         //¢ë¡®à ¬¥â®¤  á ¬¥­ì訬 à §¬¥à®¬
  794.  
  795.                         if(size2<=size0)mode=2;
  796.  
  797.                 }
  798.  
  799. //              printf("Num CASE %d Metod 0 size=%d. Metod 1 size=%d. Metod 2 size=%d\n",numcase,size0,size1,size2);
  800.  
  801.                 if(mode==2){
  802.  
  803.                         reg=AX;
  804.  
  805.                         reg0=idxregs[1];
  806.  
  807.                         if((!am32)||(am32&&(!((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket)))){
  808.  
  809.                                 if(tokr==r8)doalmath(signflag,&ofsstr);
  810.  
  811.                                 else do_e_axmath(signflag,tokr,&ofsstr);
  812.  
  813.                         }
  814.  
  815.                         else{
  816.  
  817.                                 reg=itok.number;
  818.  
  819.                                 if(reg==reg0)reg0=idxregs[0];
  820.  
  821.                                 nexttok();
  822.  
  823.                         }
  824.  
  825.                                 ClearReg(reg);
  826.  
  827.                                 ClearReg(reg0);
  828.  
  829.                         warningreg(regs[am32][reg0]);
  830.  
  831.                 }
  832.  
  833.                 else if((tok==tk_beg||tok==tk_reg||tok==tk_reg32)&&tok2==tk_closebracket){
  834.  
  835.                         if(reg==AX){
  836.  
  837.                                 reg=itok.number;
  838.  
  839.                                 if(mode&&am32)getintoreg_32(reg,r32,0,&ofsstr);
  840.  
  841.                                 else nexttok();
  842.  
  843.                                 ClearReg(AX);
  844.  
  845.                         }
  846.  
  847.                         else{
  848.  
  849.                                 getintoreg_32(BX,r16,0,&ofsstr);
  850.  
  851.                                 ClearReg(BX);
  852.  
  853.                                 warningreg("BX");
  854.  
  855.                         }
  856.  
  857.                 }
  858.  
  859.                 else{
  860.  
  861.                         if(tokr==r8)doalmath(signflag,&ofsstr);
  862.  
  863.                         else do_e_axmath(signflag,tokr,&ofsstr);
  864.  
  865.                         if(reg!=AX){
  866.  
  867.                                 ClearReg(BX);
  868.  
  869.                                 if(tokr==r8)outword(0xB4);      //mov ah,0
  870.  
  871.                                 if(optimizespeed)outword(0xC389);       //mov bx,ax
  872.  
  873.                                 else op(0x93);  //xchg ax,bx
  874.  
  875.                         }
  876.  
  877.                         else{
  878.  
  879.                                 ClearReg(AX);
  880.  
  881.                                 if(mode&&am32&&tokr!=r32){
  882.  
  883.                                         op(0x0F);
  884.  
  885.                                         op(tokr==r8?0xB6:0xB7);
  886.  
  887.                                         op(0xC0);
  888.  
  889.                                 }
  890.  
  891.                         }
  892.  
  893.                 }
  894.  
  895.                 nextexpecting2(tk_openbrace);   //¯à®¢ ­  ®âªà ᪮¡ªã
  896.  
  897.                 if(numcase){
  898.  
  899.                         if(mode==1){    //¯¥à¢ë© ¬¥â®¤
  900.  
  901.                                 if(min!=0){
  902.  
  903.                                         if(min==1)op(0x48+reg-svop);    //dec reg
  904.  
  905.                                         else if(min==2&&(!optimizespeed)){
  906.  
  907.                                                 op(0x48+reg-svop);      //dec reg
  908.  
  909.                                                 op(0x48+reg-svop);      //dec reg
  910.  
  911.                                         }
  912.  
  913.                                         else if(min<128){
  914.  
  915.                                                 op(0x83);
  916.  
  917.                                                 op(0xE8+reg-svop*5);
  918.  
  919.                                                 op(min);
  920.  
  921.                                         }
  922.  
  923.                                         else{
  924.  
  925.                                                 if(reg==AX)op(0x2D-svop*5);
  926.  
  927.                                                 else{
  928.  
  929.                                                         op(0x81);
  930.  
  931.                                                         op(0xE8+reg-svop*5);
  932.  
  933.                                                 }
  934.  
  935.                                                 if(am32)outdword(min);
  936.  
  937.                                                 else outword(min);
  938.  
  939.                                         }
  940.  
  941.                                         if(am32)warningreg(regs[1][reg]);
  942.  
  943.                                 }
  944.  
  945.                                 if(max<128){
  946.  
  947.                                         op(0x83);       //cmp reg,max
  948.  
  949.                                         op(0xF8+reg);
  950.  
  951.                                         op(max);
  952.  
  953.                                 }
  954.  
  955.                                 else{
  956.  
  957.                                         if(reg==AX)op(0x3D);
  958.  
  959.                                         else{
  960.  
  961.                                                 op(0x81);
  962.  
  963.                                                 op(0xF8+reg);
  964.  
  965.                                         }
  966.  
  967.                                         if(am32)outdword(max);
  968.  
  969.                                         else outword(max);
  970.  
  971.                                 }
  972.  
  973.                                 if(shortjmp==FALSE){
  974.  
  975.                                         if(chip<3){
  976.  
  977.                                                 outword(0x376); //jbe 3
  978.  
  979.                                                 op(0xE9);       //jmp to default
  980.  
  981.                                         }
  982.  
  983.                                         else outword(0x870F);   //ja default
  984.  
  985.                                         outword(0);
  986.  
  987.                                         if(am32)outword(0);
  988.  
  989.                                 }
  990.  
  991.                                 else{
  992.  
  993.                                         op(0x77);
  994.  
  995.                                         op(0);
  996.  
  997.                                 }
  998.  
  999.                                 endsw=outptr;   // ¤à¥á ª®­æ  switch ¨«¨ default
  1000.  
  1001.                                 if(am32){
  1002.  
  1003.                                         outword(0x24FF);
  1004.  
  1005.                                         op(0x85+reg*8);
  1006.  
  1007.                                 }
  1008.  
  1009.                                 else outdword(0xA7FFDB01);      //add bx,bx jmp [bx+table]
  1010.  
  1011.                                 AddReloc(CS);
  1012.  
  1013.                                 size1=outptr;
  1014.  
  1015.                                 outword(0);
  1016.  
  1017.                                 if(am32)outword(0);
  1018.  
  1019.                         }
  1020.  
  1021.                         else if(mode==0){
  1022.  
  1023.                                 svop=numcase;
  1024.  
  1025.                                 for(;numcase>0;){       //¢¥â¢«¥­¨¥
  1026.  
  1027.                                         numcase--;
  1028.  
  1029.                                         CmpRegNum(tokr,(caseinf+numcase)->value,reg);
  1030.  
  1031.                                         if((caseinf+numcase)->type==singlcase){
  1032.  
  1033.                                                 if(numcase){
  1034.  
  1035.                                                         if((caseinf+numcase)->postcase==FALSE){
  1036.  
  1037.                                                                 if(chip<3){
  1038.  
  1039.                                                                         outword(0x375); //jnz 3
  1040.  
  1041.                                                                         op(0xE9);       //jmp to default
  1042.  
  1043.                                                                 }
  1044.  
  1045.                                                                 else outword(0x840F);   //jz default
  1046.  
  1047.                                                                 outword(0);
  1048.  
  1049.                                                                 if(am32)outword(0);
  1050.  
  1051.                                                         }
  1052.  
  1053.                                                         else outword(0x74);
  1054.  
  1055.                                                         (caseinf+numcase)->postcase=outptr;
  1056.  
  1057.                                                 }
  1058.  
  1059.                                                 else{
  1060.  
  1061.                                                         if(shortjmp==FALSE){
  1062.  
  1063.                                                                 if(chip<3){
  1064.  
  1065.                                                                         outword(0x374); //jnz 3
  1066.  
  1067.                                                                         op(0xE9);       //jmp to default
  1068.  
  1069.                                                                 }
  1070.  
  1071.                                                                 else outword(0x850F);   //jz default
  1072.  
  1073.                                                                 outword(0);
  1074.  
  1075.                                                                 if(am32)outword(0);
  1076.  
  1077.                                                         }
  1078.  
  1079.                                                         else outword(0x75);
  1080.  
  1081.                                                         endsw=outptr;   // ¤à¥á ª®­æ  switch ¨«¨ default
  1082.  
  1083.                                                 }
  1084.  
  1085.                                         }
  1086.  
  1087.                                         else{   //case 1...5
  1088.  
  1089.                                                 numcase--;
  1090.  
  1091.                                                 max=(caseinf+numcase)->value;
  1092.  
  1093.                                                 if(numcase!=0){
  1094.  
  1095.                                                         if((caseinf+numcase+1)->postcase==FALSE){
  1096.  
  1097.                                                                 if(max==0){
  1098.  
  1099.                                                                         if(chip>2){
  1100.  
  1101.                                                                                 outdword(0x860F);
  1102.  
  1103.                                                                                 if(am32)outword(0);
  1104.  
  1105.                                                                         }
  1106.  
  1107.                                                                         else{
  1108.  
  1109.                                                                                 outword(am32==FALSE?0x0377:0x577);
  1110.  
  1111.                                                                                 jumploc0();
  1112.  
  1113.                                                                         }
  1114.  
  1115.                                                                 }
  1116.  
  1117.                                                                 else{
  1118.  
  1119.                                                                         outword(0x77);
  1120.  
  1121.                                                                         endsw=outptr;
  1122.  
  1123.                                                                         CmpRegNum(tokr,max,reg);
  1124.  
  1125.                                                                         if(chip>2){
  1126.  
  1127.                                                                                 outdword(0x830F);
  1128.  
  1129.                                                                                 if(am32)outword(0);
  1130.  
  1131.                                                                         }
  1132.  
  1133.                                                                         else{
  1134.  
  1135.                                                                                 outword(am32==FALSE?0x0372:0x572);
  1136.  
  1137.                                                                                 jumploc0();
  1138.  
  1139.                                                                         }
  1140.  
  1141.                                                                         output[endsw-1]=(unsigned char)(outptr-endsw);
  1142.  
  1143.                                                                 }
  1144.  
  1145.                                                         }
  1146.  
  1147.                                                         else{
  1148.  
  1149.                                                                 if(max==0)outword(0x76);
  1150.  
  1151.                                                                 else{
  1152.  
  1153.                                                                         outword(0x77);
  1154.  
  1155.                                                                         endsw=outptr;
  1156.  
  1157.                                                                         CmpRegNum(tokr,max,reg);
  1158.  
  1159.                                                                         outword(0x73);
  1160.  
  1161.                                                                         output[endsw-1]=(unsigned char)(outptr-endsw);
  1162.  
  1163.                                                                 }
  1164.  
  1165.                                                         }
  1166.  
  1167.                                                         (caseinf+numcase)->postcase=outptr;
  1168.  
  1169.                                                 }
  1170.  
  1171.                                                 else{
  1172.  
  1173.                                                         if(shortjmp==FALSE){
  1174.  
  1175.                                                                 if((optimizespeed&&chip>2)||(chip>2&&max==0)){
  1176.  
  1177.                                                                         outdword(0x870F);
  1178.  
  1179.                                                                         if(am32)outword(0);
  1180.  
  1181.                                                                         if(max!=0){
  1182.  
  1183.                                                                                 endsw2=outptr;
  1184.  
  1185.                                                                                 CmpRegNum(tokr,max,reg);
  1186.  
  1187.                                                                                 outdword(0x820F);
  1188.  
  1189.                                                                                 if(am32)outword(0);
  1190.  
  1191.                                                                         }
  1192.  
  1193.                                                                 }
  1194.  
  1195.                                                                 else{
  1196.  
  1197.                                                                         if(max==0) outword(am32==FALSE?0x0376:0x576);
  1198.  
  1199.                                                                         else{
  1200.  
  1201.                                                                                 outword(0x77);
  1202.  
  1203.                                                                                 endsw=outptr-1;
  1204.  
  1205.                                                                                 CmpRegNum(tokr,max,reg);
  1206.  
  1207.                                                                                 outword(am32==FALSE?0x0373:0x573);
  1208.  
  1209.                                                                                 output[endsw]=(unsigned char)(outptr-endsw-1);
  1210.  
  1211.                                                                         }
  1212.  
  1213.                                                                         jumploc0();
  1214.  
  1215.                                                                 }
  1216.  
  1217.                                                         }
  1218.  
  1219.                                                         else{
  1220.  
  1221.                                                                 outword(0x77);
  1222.  
  1223.                                                                 if(max!=0){
  1224.  
  1225.                                                                         endsw2=outptr;
  1226.  
  1227.                                                                         CmpRegNum(tokr,max,reg);
  1228.  
  1229.                                                                         outword(0x72);
  1230.  
  1231.                                                                 }
  1232.  
  1233.                                                         }
  1234.  
  1235.                                                         endsw=outptr;   // ¤à¥á ª®­æ  switch ¨«¨ default
  1236.  
  1237.                                                 }
  1238.  
  1239.                                         }
  1240.  
  1241.                                 }
  1242.  
  1243.                         }
  1244.  
  1245.                         else if(mode==2){
  1246.  
  1247.                                 if(!am32){
  1248.  
  1249.                                         outdword(0x071E0651);   //push cx,es,ds pop es
  1250.  
  1251.                                         op(0xB9);       //mov CX,numcase
  1252.  
  1253.                                         outword(numcase+numexpandcase);
  1254.  
  1255.                                         op(0xBF);       //mov DI,tableval
  1256.  
  1257.                                         AddReloc(CS);
  1258.  
  1259.                                         size2=outptr;
  1260.  
  1261.                                         outword(0);
  1262.  
  1263.                                         op(0xF2);       //repnz
  1264.  
  1265.                                         switch(tokr){
  1266.  
  1267.                                                 case r8: op(0xAE); break;
  1268.  
  1269.                                                 case r32: op(0x66);
  1270.  
  1271.                                                 case r16: op(0xAF); break;
  1272.  
  1273.                                         }
  1274.  
  1275.                                         outword(0x7407);        //pop es ,jz
  1276.  
  1277.                                         op(shortjmp==FALSE?4:3);
  1278.  
  1279.                                         op(0x59);       //pop cx
  1280.  
  1281.                                         if(shortjmp==FALSE)jumploc0();
  1282.  
  1283.                                         else outword(0xEB);
  1284.  
  1285.                                         endsw=outptr;   // ¤à¥á ª®­æ  switch ¨«¨ default
  1286.  
  1287.                                         op(0xBF);       //mov DI,numcase
  1288.  
  1289.                                         outword(numcase+numexpandcase);
  1290.  
  1291.                                         outdword(0x014FCF29);   //sub di,cx dec di add di,di
  1292.  
  1293.                                         op(0xFF);
  1294.  
  1295.                                         outword(0xC781);        //add di,tableadr
  1296.  
  1297.                                         AddReloc(CS);
  1298.  
  1299.                                         size1=outptr;
  1300.  
  1301.                                         outword(0);
  1302.  
  1303.                                         op(0x59);       //pop cx
  1304.  
  1305.                                         outword(0x25FF);        //jmp [di]
  1306.  
  1307.                                 }
  1308.  
  1309.                                 else{
  1310.  
  1311.                                         op(0x31);
  1312.  
  1313.                                         op(0xC0+reg0*9);        //xor reg0,reg0
  1314.  
  1315.                                         switch(tokr){   //cmp [reg0*size+tableadr],reg
  1316.  
  1317.                                                 case r8: op(0x38); op(0x4+reg*8); op(5+reg0*8); break;
  1318.  
  1319.                                                 case r32: op(0x39); op(0x4+reg*8); op(0x85+reg0*8); break;
  1320.  
  1321.                                                 case r16: op(0x66); op(0x39); op(0x4+reg*8); op(0x45+reg0*8); break;
  1322.  
  1323.                                         }
  1324.  
  1325.                                         AddReloc(CS);
  1326.  
  1327.                                         size2=outptr;
  1328.  
  1329.                                         outdword(0);
  1330.  
  1331.                                         outword(0x0775);        //jne
  1332.  
  1333.                                         outword(0x24FF);        //jmp [reg0*4+tableadr]
  1334.  
  1335.                                         op(0x85+reg0*8);
  1336.  
  1337.                                         AddReloc(CS);
  1338.  
  1339.                                         size1=outptr;
  1340.  
  1341.                                         outdword(0);
  1342.  
  1343.                                         op(0x40+reg0);  //inc reg0
  1344.  
  1345.                                         if((numcase+numexpandcase)>127){        //cmp reg0,numcase
  1346.  
  1347.                                                 op(0x81);
  1348.  
  1349.                                                 op(0xF8+reg0);
  1350.  
  1351.                                                 outdword(numcase+numexpandcase);
  1352.  
  1353.                                         }
  1354.  
  1355.                                         else{
  1356.  
  1357.                                                 op(0x83);
  1358.  
  1359.                                                 op(0xF8+reg0);
  1360.  
  1361.                                                 op(numcase+numexpandcase);
  1362.  
  1363.                                         }
  1364.  
  1365.                                         op(0x72);
  1366.  
  1367.                                         if((numcase+numexpandcase)>127)op(tokr==r16?0xE6:0xE7);
  1368.  
  1369.                                         else op(tokr==r16?0xE9:0xEA);
  1370.  
  1371.                                         if(shortjmp==FALSE)jumploc0();
  1372.  
  1373.                                         else outword(0xEB);
  1374.  
  1375.                                         endsw=outptr;   // ¤à¥á ª®­æ  switch ¨«¨ default
  1376.  
  1377.                                 }
  1378.  
  1379.                         }
  1380.  
  1381.                 }
  1382.  
  1383.                 numcase=0;
  1384.  
  1385.                 useinline=oinline;
  1386.  
  1387.                 bakregstat=BakRegStat();
  1388.  
  1389.                 changeregstat=BakRegStat();
  1390.  
  1391.                 lastcommand=tk_switch;
  1392.  
  1393.                 do{
  1394.  
  1395.                         if(tok==tk_case||tok==tk_CASE||tok==tk_default){     //¥á«¨ case - § ¯®¬­¨âì ¯®§¨æ¨î ¨ ¢¥«¨ç¨­ã
  1396.  
  1397.                                 RestoreStack();
  1398.  
  1399.                                 CompareRegStat(changeregstat);
  1400.  
  1401.                                 switch(lastcommand){
  1402.  
  1403.                                         case tk_goto:
  1404.  
  1405.                                         case tk_GOTO:
  1406.  
  1407.                                         case tk_break:
  1408.  
  1409.                                         case tk_BREAK:
  1410.  
  1411.                                         case tk_return:
  1412.  
  1413.                                         case tk_RETURN:
  1414.  
  1415.                                         case tk_switch:
  1416.  
  1417.                                                 CopyRegStat(bakregstat);
  1418.  
  1419. #ifdef OPTVARCONST
  1420.  
  1421.                                                 nonum=FALSE;
  1422.  
  1423. #endif
  1424.  
  1425.                                                 addESP=oaddESP;
  1426.  
  1427.                                                 break;
  1428.  
  1429.                                         default:
  1430.  
  1431.                                                 CopyRegStat(changeregstat);
  1432.  
  1433. #ifdef OPTVARCONST
  1434.  
  1435.                                                 nonum=TRUE;
  1436.  
  1437. #endif
  1438.  
  1439.                                                 if(ESPloc&&am32&&oaddESP!=addESP)warESP();
  1440.  
  1441.                                                 break;
  1442.  
  1443.                                 }
  1444.  
  1445.                                 if(tok==tk_default){    //⮦¥ ¤«ï default
  1446.  
  1447.                                         if(mode==0&&svop){
  1448.  
  1449.                                                 if(numcase==0)jumploc0();       //default á ¬ë© ¯¥à¢ë©
  1450.  
  1451.                                                 CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);
  1452.  
  1453.                                                 if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);
  1454.  
  1455.                                         }
  1456.  
  1457.                                         if(defaul)preerror("Duplicate 'default'");
  1458.  
  1459.                                         defaul=outptr;
  1460.  
  1461.                                         nexttok();
  1462.  
  1463.                                         expecting(tk_colon);    //¯à®¢ ­  : ¨ ç⥭¨¥ á«¥¤ãîé tok
  1464.  
  1465.                                         continue;
  1466.  
  1467.                                 }
  1468.  
  1469.                                 if(mode==0){
  1470.  
  1471.                                         if(numcase==0&&defaul){ //default á ¬ë© ¯¥à¢ë©
  1472.  
  1473.                                                 if(am32==FALSE)*(unsigned short *)&output[defaul-2]=(unsigned short)(outptr-defaul);
  1474.  
  1475.                                                 else *(unsigned long *)&output[defaul-4]=(unsigned long)(outptr-defaul);
  1476.  
  1477.                                         }
  1478.  
  1479.                                         else if(numcase)CheckJmpSW(linenumber,(caseinf+numcase)->postcase,outptr,tok==tk_case?FALSE:TRUE,mesCASE);
  1480.  
  1481.                                 }
  1482.  
  1483.                                 else (caseinf+numcase)->postcase=outptr;
  1484.  
  1485.                                 lastcommand=tok;        //new 12.12.07 14:27
  1486.  
  1487.                                 nexttok();
  1488.  
  1489. #ifdef OPTVARCONST
  1490.  
  1491.                                 numrm=itok.rm;
  1492.  
  1493.                                 numbervar=doconstlongmath();
  1494.  
  1495.                                 (caseinf+numcase)->value=numbervar-(mode==1?smin:0);
  1496.  
  1497. #else
  1498.  
  1499.                                 (caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0);
  1500.  
  1501. #endif
  1502.  
  1503.                                 numcase++;
  1504.  
  1505.                                 if(tok==tk_multipoint){
  1506.  
  1507.                                         nexttok();
  1508.  
  1509.                                         (caseinf+numcase)->value=doconstlongmath()-(mode==1?smin:0);
  1510.  
  1511.                                         numcase++;
  1512.  
  1513.                                 }
  1514.  
  1515. #ifdef OPTVARCONST
  1516.  
  1517.                                 else if(swvar&&nonum==FALSE)Const2Var(&otok,numbervar,numrm);
  1518.  
  1519. #endif
  1520.  
  1521.                                 expecting(tk_colon);    //¯à®¢ ­  : ¨ ç⥭¨¥ á«¥¤ãîé tok
  1522.  
  1523.                                 if(tok==tk_closebrace)numcase--;
  1524.  
  1525.                                 continue;//goto checkcase;
  1526.  
  1527.                         }
  1528.  
  1529.                         startblock();
  1530.  
  1531.                         docommand();
  1532.  
  1533.                         endblock();
  1534.  
  1535.                 }while(tok!=tk_closebrace);
  1536.  
  1537.                 RestoreStack();
  1538.  
  1539.                 if(numberbreak==0){
  1540.  
  1541.                         switch(lastcommand){
  1542.  
  1543.                                 case tk_break:
  1544.  
  1545.                                         posts--;
  1546.  
  1547.                                         outptr-=(am32==FALSE?3:5);
  1548.  
  1549.                                         break;
  1550.  
  1551.                                 case tk_BREAK:
  1552.  
  1553.                                         posts--;
  1554.  
  1555.                                         outptr-=2;
  1556.  
  1557.                                         break;
  1558.  
  1559.                         }
  1560.  
  1561.                 }
  1562.  
  1563.                 if(defaul&&outptr<defaul){
  1564.  
  1565.                         if(mode==0&&svop){
  1566.  
  1567.                                 if(numcase==0)jumploc0();       //default á ¬ë© ¯¥à¢ë©
  1568.  
  1569.                                 CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);
  1570.  
  1571.                                 if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);
  1572.  
  1573.                         }
  1574.  
  1575.                         defaul=outptr;
  1576.  
  1577.                 }
  1578.  
  1579. //              printf("outptr=%08X defaul=%08X\n",outptr,defaul);
  1580.  
  1581.                 CompareRegStat(changeregstat);
  1582.  
  1583.                 FreeStat(bakregstat);
  1584.  
  1585.                 CopyRegStat(changeregstat);
  1586.  
  1587.                 FreeStat(changeregstat);
  1588.  
  1589.                 if(numcase){
  1590.  
  1591.                         if(mode==0){
  1592.  
  1593.                                 if(defaul==0){
  1594.  
  1595.                                         CheckJmpSW(sline,endsw,outptr,shortjmp,mesSWITCH);
  1596.  
  1597.                                         if(endsw2)CheckJmpSW(sline,endsw2,outptr,shortjmp,mesSWITCH);
  1598.  
  1599.                                 }
  1600.  
  1601.                                 free(caseinf);
  1602.  
  1603.                         }
  1604.  
  1605.                         else{
  1606.  
  1607.                                 if(defaul==0||defaul>outptr)defaul=outptr;
  1608.  
  1609.                                 CheckJmpSW(sline,endsw,defaul,shortjmp,mesSWITCH);
  1610.  
  1611.                                 caseinf=(ISW *)REALLOC(caseinf,sizeof(ISW)*numcase);
  1612.  
  1613.                                 if(!numswtable)swtables=(FSWI *)MALLOC(sizeof(FSWI));
  1614.  
  1615.                                 else swtables=(FSWI *)REALLOC(swtables,sizeof(FSWI)*(numswtable+1));
  1616.  
  1617.                                 FSWI *swt=swtables+numswtable;
  1618.  
  1619.                                 swt->info=caseinf;
  1620.  
  1621.                                 swt->sizetab=(mode==2?numcase:sizetab)+numexpandcase;
  1622.  
  1623.                                 swt->type=(am32==FALSE?2:4);
  1624.  
  1625.                                 swt->numcase=numcase;
  1626.  
  1627.                                 swt->defal=defaul;
  1628.  
  1629.                                 swt->ptb=size1;
  1630.  
  1631.                                 swt->ptv=size2;
  1632.  
  1633.                                 swt->mode=mode;
  1634.  
  1635.                                 swt->razr=tokr;
  1636.  
  1637.                                 numswtable++;
  1638.  
  1639.                         }
  1640.  
  1641.                 }
  1642.  
  1643.                 else free(caseinf);
  1644.  
  1645.                 SetBreakLabel();
  1646.  
  1647.                 SetContinueLabel();
  1648.  
  1649.         }
  1650.  
  1651.         nexttok();
  1652.  
  1653.         lastcommand=tk_switch;
  1654.  
  1655.         retproc=FALSE;
  1656.  
  1657. }
  1658.  
  1659.