コード例 #1
0
//"表达式"语法分析
bool KH::GrammarPL0::ExpressionParsing()//nIndentNum是打印时要缩进的空格数
{
	bool result = true;

	if( GetWord(false).GetSign() == KH::_PLUS ||  GetWord(false).GetSign() == KH::_MINUS)
	{//如果开头有正负号,则此时表达式应被看作一个正的或负的项

		//Gen  +-
			GenPush(GetWord(false).GetValue());

		 skip(1);
	}

	if( TermParsing() )//表达式可以是一个"项"
	{
		while( GetWord(false).GetSign() == KH::_PLUS ||  GetWord(false).GetSign() == KH::_MINUS)
		{	
			//Gen  +-
			GenPush(GetWord(false).GetValue());

			 skip(1);
			if( !TermParsing() ){
				Error( result," Expression Parsing Error , There should be a Term ." );
			}
		}
	}
	else 
	{
		Error( result," Expression Parsing Error , There should be a Term .");
	}

	return result;
}
コード例 #2
0
//条件
bool KH::GrammarPL0::ConditionParsing()//nIndentNum是打印时要缩进的空格数
{
	bool result = true;

	if( GetWord(false).GetSign() == KH::_ODD)//如果有"odd"单词
	{
		//Gen  if (
				GenPush("( "); //注意闭合!

		 skip(1);
		if(! ExpressionParsing()) {
			Error( result," Condition Parsing Error , There should be a Expression .");
		}

		//Gen  if .. )
				GenPush(" ) "); //注意闭合!
	}
	else
	{
		//Gen  if (
				GenPush(" ( "); //注意闭合!

		if(! ExpressionParsing()) {
			Error( result," Condition Parsing Error , There should be a Expression .");
		}
		if(		 GetWord(false).GetSign() == KH::_EQUAL	//如果后面有逻辑运算符
			||	 GetWord(false).GetSign() == KH::_NEQUAL
			||	 GetWord(false).GetSign() == KH::_LANGLE
			||	 GetWord(false).GetSign() == KH::_LEQUAL
			||	 GetWord(false).GetSign() == KH::_RANGLE
			||	 GetWord(false).GetSign() == KH::_REQUAL)
		{
			//Gen  if ( == )
				GenPush(GetWord(false).GetValue()); //注意闭合!

			 skip(1);
			if(! ExpressionParsing()) {
				Error( result," Condition Parsing Error , There should be a Expression .");
			}
		}
		else
		{
			Error( result," Condition Parsing Error , Logic Error : " + GetWord(false).GetValue());
		}

		//Gen  if .. )
			GenPush(" ) "); //注意闭合!
	}
	return result;
}
コード例 #3
0
//"因子"语法分析
bool KH::GrammarPL0::FactorParsing()
{
	bool result = true;

	switch( GetWord(false).GetSign())
	{
		case KH::_IDENTIFIER://因子可以是一个常量或变量
			Sa.ExistVariable(GetLine(),GetWord(false).GetValue());

			//Gen  ident
			GenPush(GetWord(false).GetValue());
			 skip(1);
			break;

		case KH::_INT:	//因子可以是一个数
		case KH::_FLOAT:
			//Gen  ident
			GenPush(GetWord(false).GetValue());
			 skip(1);
			break;

		case KH::_LPAREN :	//如果看到左括号'('
			//Gen (
			GenPush(" ( ");
			 skip(1);

			if(!ExpressionParsing())
			{
				Error( result," Factor Error , There should be a Expression .");
			}

			if( GetWord(false).GetSign() == KH::_RPAREN)//"表达式"后面应是右括号')'
			{
				//Gen )
				GenPush(" ) ");
				 skip(1);
			}
			else{
				Error( result," Factor Error , There should be a Right Paren : " + GetWord(false).GetValue());
			}

			break;

		default:	
			Error( result," Factor Error , There should be a Factor .");
			break;
	}//End of switch
	return result;
}
コード例 #4
0
void CodeGenerator::GenNegate()
{
   GenBlockHeader( "Negate" );
   GenPop( "eax" );
   GenLine( "neg eax" );
   GenPush( "eax" );
}
コード例 #5
0
void CodeGenerator::GenAssign( std::string addrTo )
{
   GenBlockHeader( "Assignment" );
   GenPop( "eax" );
   GenMov( addrTo, "eax" );
   GenPush( "eax" );
}
コード例 #6
0
void CodeGenerator::GenFuncCall( std::string funcName, int paramCountCall )
{
   GenReverseStack( paramCountCall );
   GenBlockHeader( "Call " + funcName + " Function" );
   GenLine( "CALL _" + funcName );
   GenLine( "add esp, " + toString( 4 * paramCountCall ) + "d" );
   GenPush( "eax" );
}
コード例 #7
0
void CodeGenerator::GenMultiplication()
{
   GenBlockHeader( "Multiply" );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenLine( "imul ecx" );
   GenPush( "eax" );
}
コード例 #8
0
void CodeGenerator::GenStringPush( std::string str )
{
   std::string strVar = "S" + toString( mStrCount++ );
   GenLine( ".data" );
   GenLine( strVar + " BYTE \"" + str + "\", 00h" );
   GenLine( ".code" );
   GenPush( "OFFSET " + strVar );
}
コード例 #9
0
// GenBinaryOperation
void CodeGenerator::GenBinaryOperation( std::string operationName )
{
   GenBlockHeader( operationName );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenLine( operationName + " eax, ecx" );
   GenPush( "eax" );
}
コード例 #10
0
void CodeGenerator::GenDivision()
{
   GenBlockHeader( "Divide" );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenLine( "CDQ" );
   GenLine( "idiv ecx" );
   GenPush( "eax" );
}
コード例 #11
0
int CodeGenerator::GenFuncStart( std::string funcName )
{
   GenBlockHeader( "Function " + funcName + " Declaration" );
   funcName = '_' + funcName;
   GenLine( "PUBLIC " + funcName );
   GenLine( funcName + " PROC" );
   GenPush( "ebp" );
   GenMov( "ebp","esp" );
   GenLine();
   return CreateLabel();
}
コード例 #12
0
void CodeGenerator::GenNot()
{
   GenBlockHeader( "Not" );
   GenPop( "eax" );
   GenMov( "edx", "0" );
   GenLine( "cmp eax, 0" );
   GenLine( "JNE L" + toString( ++mLabelCount ) );
   GenLine( "inc edx" );
   GenLabel( mLabelCount );
   GenPush( "edx" );
}
コード例 #13
0
void CodeGenerator::GenOr()
{
   GenBlockHeader( "Or" );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenMov( "edx", "0" );
   GenLine( "or eax, ecx" );
   GenLine( "cmp eax, 0" );
   GenLine( "JE L" + toString( ++mLabelCount ) );
   GenLine( "inc edx" );
   GenLabel( mLabelCount );
   GenPush( "edx" );
}
コード例 #14
0
void CodeGenerator::GenAnd()
{
   GenBlockHeader( "And" );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenLine( "imul ecx" );
   GenMov( "edx", "0" );
   GenLine( "cmp eax, 0" );
   mAsmCode += "JE";
   mAsmCode += " L" + toString( ++mLabelCount ) + "\n";
   GenLine( "inc edx" );
   GenLabel( mLabelCount );
   GenPush( "edx" );
}
コード例 #15
0
void CodeGenerator::GenCompare( std::string sign )
{
   GenBlockHeader( "Compare" );
   GenPop( "ecx" );
   GenPop( "eax" );
   GenMov( "edx", "0" );
   GenLine( "cmp eax, ecx" );
   if( sign == "==" ) mAsmCode += "JNE ";
   if( sign == "!=" ) mAsmCode += "JE";
   if( sign == ">" ) mAsmCode += "JLE";
   if( sign == "<" ) mAsmCode += "JGE";
   if( sign == ">=" ) mAsmCode += "JL";
   if( sign == "<=" ) mAsmCode += "JG";
   mAsmCode += " L" + toString( ++mLabelCount ) + "\n";
   GenLine( "inc edx" );
   GenLabel( mLabelCount );
   GenPush( "edx" );
}
コード例 #16
0
//"项"语法分析
bool KH::GrammarPL0::TermParsing()//nIndentNum是打印时要缩进的空格数
{
	bool result = true;

	if(! FactorParsing()){
		Error( result," Term Parsing Error , There should be a Factor .");
	}

	while( GetWord(false).GetSign() == KH::_TIMES ||  GetWord(false).GetSign() == KH::_SLASH)
	{//如果"因子"后面还有单词'*'或'/'
		//Gen  */
			GenPush(GetWord(false).GetValue());
		 skip(1);
		if(!FactorParsing()){
			Error( result," Term Parsing Error , There should be a Factor .");
		}
	}

	return result;
}
コード例 #17
0
void CodeGenerator::GenReverseStack( int depth )
{
   if( depth < 2 ) return;
   GenBlockHeader( "Reversing last " + toString( depth ) + " stack items" );
   GenLine( ".data" );
   // allocate enough memory
   for( int i = 1; i <= depth; ++i )
   {
      GenLine( "stackReveseVar" + toString( mStackReverseCount++ ) + " DWORD ?" );
   }
   GenLine( ".code" );
   // pop into memory
   for( int i = depth; i >= 1; --i )
   {
      GenPop( "stackReveseVar" + toString( mStackReverseCount - i ) );
   }
   for( int i = depth; i >= 1; --i )
   {
      GenPush( "stackReveseVar" + toString( mStackReverseCount - i ) );
   }
}
コード例 #18
0
bool KH::GrammarPL0::StatementParsing(){

	bool result = true;

	switch( GetWord(false).GetSign()){
		case KH::_IDENTIFIER: //Identifire
			Sa.ExistVariable(GetLine(),GetWord(false).GetValue());

			//Gen a = ..
			GenPush(GetWord(false).GetValue() + " = ");//注意闭合

			 skip(1);
			if( GetWord(0,false).GetSign() == KH::_ASSIGN){
				//Gen )
				 skip(1);
				if(!ExpressionParsing())
					Error( result," Statement Error , There should be a Expression .");
			}
			else{
				Error( result," Statement Error , Assign required : " + GetWord(false).GetValue());
			}

			//Gen a = .. ;
			GenPush(" ; ");//注意闭合

			break;
		case KH::_CALL:	//Call
			 skip(1);
			if( GetWord(0,false).GetSign() == KH::_IDENTIFIER){
				Sa.ExistVariable(GetLine(),GetWord(false).GetValue());

				//Gen a();
				GenPush(GetWord(false).GetValue() + " () ;");
				 skip(1);
			}
			else{
				Error( result," Statement Error , Identifier required : " + GetWord(false).GetValue());
			}
			break;
		case KH::_LBIGPAREN: //Begin
		case KH::_BEGIN:
			 skip(1);
			 //Gen { 
			GenPush(" { ");//注意闭合
			if(Block()){
				while( GetWord(0,false).GetSign() == KH::_SEMICOLON){
					//Gen ;
						GenPush(";");
					skip(1);
					if(GetWord(0,false).GetSign() == KH::_END || GetWord(0,false).GetSign() == KH::_RBIGPAREN) {
						break;
					}
					if(!StatementParsing())
						Error( result," Statement Error , Statement required .");
				}

				if(	 GetWord(0,false).GetSign() == KH::_RBIGPAREN || 
					 GetWord(0,false).GetSign() == KH::_END)
				{
					//Gen }
						GenPush(" } ");//注意闭合
					 skip(1);
				}
				else
					Error( result," Statement Error , 'end' or '}' required : " + GetWord(false).GetValue() );
			}
			else{
				Error( result," Statement Error , Statement required .");
			}

			break;
		case KH::_IF:
			//Gen if
				GenPush(" if ");
			 skip(1);
			if( ConditionParsing()){
				 //skip(1);
				if( GetWord(0,false).GetSign() == KH::_THEN){
					//Gen if .. { }
					GenPush(" { ");
					 skip(1);
					if(!StatementParsing())
						Error( result," Statement Error , Statement required .");
					//Gen if .. { }
					GenPush(" } ");
				}
				else{
					Error( result," Statement Error , 'Then' required : " + GetWord(false).GetValue());
				}
			}
			else{
				Error( result," Statement Error , Condition required .");
			}
			break;
		case KH::_WHILE:
			//Gen while
				GenPush(" while ");
			 skip(1);
			if( ConditionParsing()){
				if( GetWord(0,false).GetSign() == KH::_DO){
					//Gen while .. {}
					GenPush(" { ");

					 skip(1);
					if(!StatementParsing())
						Error( result," Statement Error , Statement required .");

					//Gen while .. {}
					GenPush(" } ");
				}
				else{
					Error( result," Statement Error , 'Do' required : " + GetWord(false).GetValue());
				}
			}
			else{
				Error( result," Statement Error , Condition required .");
			}
			break;
		case KH::_READ:
			 skip(1);
			if( GetWord(0,false).GetSign() == KH::_LPAREN &&  GetWord(1,false).GetSign() == KH::_IDENTIFIER){
				Sa.ExistVariable(GetLine(),GetWord(1,false).GetValue());
				//Gen read
					GenPush(" scanf(\"%lf\" , &" + GetWord(1,false).GetValue() + ") ;");
				 skip(2);
				 while( GetWord(0,false).GetSign() == KH::_COMMA){
					 skip(1);
					if( GetWord(0,false).GetSign() == KH::_IDENTIFIER){
						Sa.ExistVariable(GetLine(),GetWord(false).GetValue());
						//Gen read
							GenPush(" scanf(\"%lf\" , &" + GetWord(0,false).GetValue() + ") ;");
						 skip(1);
					}
					else Error( result," Statement Error , Identifire required : " + GetWord(false).GetValue());
				}

				if(	 GetWord(0,false).GetSign() == KH::_RPAREN )
				{
					 skip(1);
				}
				else
					Error( result," Statement Error , ')' required : " + GetWord(false).GetValue());
			}
			else{
				Error( result," Statement Error , Identifire required : " + GetWord(false).GetValue());
			}
			break;
		case KH::_WRITE:
			 skip(1);
			if( GetWord(0).GetSign() == KH::_LPAREN ){
				//Gen write(.. 
					GenPush(" printf(\"%g \\n \" , ");
				 skip(1);
				if(ExpressionParsing()){
					//Gen write .. a .. 
					GenPush(" ) ;");
					while( GetWord(0,false).GetSign() == KH::_COMMA){
						//Gen write .. ,
							GenPush(" printf(\"%g \\n \" , ");
						 skip(1);
						if(!ExpressionParsing())
							Error( result," Statement Error , 【Expression required】 .");
						//Gen write .. ,
							GenPush(" ) ; ");
					}
				}
				else
				{
					Error( result," Statement Error , 【First Expression required】 .");
				}

				if(	 GetWord(0,false).GetSign() == KH::_RPAREN )
				{
					 skip(1);
				}
				else
					Error( result," Statement Error , 【Right Paren required】 .");
			}
			else{
				Error( result," Statement Error , 【Left Paren required】 .");
			}
			break;
		case KH::_SEMICOLON:
			 skip(1);
			break;
		default:
			Error( result," Statement Error , 【Unexpected word " + GetWord(0,false).GetValue() + "】 .",false);
			break;
	}

	return result;

}
コード例 #19
0
//分程序语法判断
bool KH::GrammarPL0::Block(){
	bool result = true;

	if( GetWord(false).GetSign() == KH::_BLOCK) skip(1); //自然会跳过所有的block
	if( CheckEnd()) {
		Error( result, " Empty Input ! " );
		return false;
	}

	if( GetWord(false).GetSign() == KH::_CONST){
		 skip(1);
		if( GetWord(false).GetSign() == KH::_IDENTIFIER){
			if(	 GetWord(1,false).GetSign() == KH::_ASSIGN &&
				 GetWord(2,false).GetSign() == KH::_INT ||
				 GetWord(2,false).GetSign() == KH::_FLOAT 
				) 
			{
				Sa.PushVariable(GetLine(),GetWord(false).GetValue());

				//Gen  int a = 11
				if(GetWord(2,false).GetSign() == KH::_INT)
					GenPush("const int " + GetWord(false).GetValue() + " = " + GetWord(2,false).GetValue() + "; " );
				else
					GenPush("const float " + GetWord(false).GetValue() + " = " + GetWord(2,false).GetValue() + "; " );
				
				 skip(3,false);
				while( GetWord(false).GetSign() == KH::_COMMA){
					if(	 GetWord(1,false).GetSign() == KH::_IDENTIFIER &&
						 GetWord(2,false).GetSign() == KH::_ASSIGN &&
						 GetWord(3,false).GetSign() == KH::_INT ||
						 GetWord(3,false).GetSign() == KH::_FLOAT 
						)
					{
						Sa.PushVariable(GetLine(),GetWord(1,false).GetValue());

						//Gen  , int a = 11
						if(GetWord(3,false).GetSign() == KH::_INT)
							GenPush("const int " + GetWord(1,false).GetValue() + " = " + GetWord(3,false).GetValue() + "; " );
						else
							GenPush("const float " + GetWord(1,false).GetValue() + " = " + GetWord(3,false).GetValue() + "; " );

						 skip(4,false);
					}
					else
					{
						Error( result, " Const Loop Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() + GetWord(2,false).GetValue() + GetWord(3,false).GetValue() );
						break;
					}
				}
				if( GetWord(false) == KH::_SEMICOLON)
					 skip(1);
				else{
					Error( result, " Const Not End : " + GetWord(false).GetValue() );
				}
			}
			else
			{
				Error( result, " Const sentence Error : " + GetWord(false).GetValue() );
			}

		}
		else
		{
			Error( result, " Const Identifier Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() + GetWord(2,false).GetValue() );
		}
	}//End of if const ;

	if( GetWord(false).GetSign() == KH::_VAR)//如果单词是"var"
	{
		 skip(1);//取下一个单词
		if( GetWord(false).GetSign() == KH::_IDENTIFIER){
			Sa.PushVariable(GetLine(),GetWord(false).GetValue());

			//Gen  var a
			GenPush("double " + GetWord(false).GetValue() + " = 0 ; " );
			 skip(1);
			while( GetWord(false).GetSign() == KH::_COMMA){
				if(	 GetWord(1,false).GetSign() == KH::_IDENTIFIER )
				{
					Sa.PushVariable(GetLine(),GetWord(1,false).GetValue());

					//Gen  var .. , a
					GenPush("double " + GetWord(1,false).GetValue() + " = 0 ; " );
					 skip(2);
				}
				else
				{
					Error( result," Var Loop Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue());
					break;
				}
			}
			if( GetWord(false).GetSign() == KH::_SEMICOLON){
				 skip(1);
			}
			else 
			{
				Error( result," Var Not End : " + GetWord(false).GetValue() );
			}
		}
		else
		{
			Error( result," Var Identifier Error : " + GetWord(false).GetValue() );
		}
	}//End of if var

	while ( GetWord(false).GetSign() == KH::_PROC)//如果单词是"procedure",则进入"函数定义"语法分析
	{
		 skip(1);
		if(	 GetWord(false).GetSign() == KH::_IDENTIFIER && 
			 GetWord(1,false).GetSign() == KH::_SEMICOLON)//"procedure"后应为标识符
		{
			Sa.PushVariable(GetLine(),GetWord(false).GetValue());

			//Gen  var .. , a
				GenPush("double " + GetWord(false).GetValue() + "( ) { " ); //注意闭合!
				funcNames.push_back(GetWord(false).GetValue());

			 skip(2);
			 Block();

			 //Gen  var .. , a
			 GenPush(" return 0 ; } " ); //注意闭合!

		}
		else{
			Error( result," Proc define Error : " + GetWord(false).GetValue() + GetWord(1,false).GetValue() ) ;
		}
	}//End of if procedure

	if(!StatementParsing()){
		Error( result," Parsing Error . " );
	}//End of if Parsing

	return result;
}
コード例 #20
0
ファイル: AN386.c プロジェクト: LADSoft/Simple-MSIL-Compiler
void allocate(int datareg, int addreg, int floatreg, SNODE *block)
/*
 *      allocate will allocate registers for the expressions that have
 *      a high enough desirability.  It also puts the function
 * header, consisting of saved registers and stack decrments for local
 * variables
 */
{
    CSE *csp;
    ENODE *exptr;
    unsigned mask, rmask, i, fmask, frmask, size;
    AMODE *ap,  *ap2;
    mask = asmMask;
    rmask = asmRMask;
    fmask = frmask = 0;
    for (i = cf_freedata; i < datareg; i++)
    {
        rmask = rmask | (1 << (15-i));
        mask = mask | (1 << i);
    }
    for (i = cf_freeaddress + 16; i < addreg; i++)
    {
        rmask = rmask | (1 << (23-i));
        mask = mask | (1 << (i - 8));
    }
    while (bsort(&olist))
        ;
     /* sort the expression list */
    csp = olist;
    while (csp != 0)
    {
        if (csp->reg ==  - 1 && !(csp->exp->cflags &DF_VOL) && !csp->voidf)
        {
            if (desire(csp) < 3)
                csp->reg =  - 1;
            else
            {
                if (csp->exp->nodetype == en_rcon || csp->exp->nodetype ==
                    en_fcon || csp->exp->nodetype == en_lrcon || csp->exp
                    ->nodetype == en_floatref || csp->exp->nodetype ==
                    en_doubleref || csp->exp->nodetype == en_longdoubleref ||
                    csp->exp->nodetype == en_fimaginarycon || 
                    csp->exp->nodetype == en_rimaginarycon ||
                    csp->exp->nodetype == en_lrimaginarycon ||
                    csp->exp->nodetype == en_fimaginaryref || 
                    csp->exp->nodetype == en_rimaginaryref ||
                    csp->exp->nodetype == en_lrimaginaryref) {}
                else if ((csp->duses <= csp->uses / 4) && (datareg < cf_maxdata)
                    && dataregs)
                    csp->reg = (datareg)++;
                else if (!(csp->size == 1 || csp->size ==  - 1 || csp->size ==
                    5) && (addreg < cf_maxaddress) && addrregs)
                    csp->reg = (addreg)++;
                else if ((datareg < cf_maxdata) && dataregs)
                    csp->reg = (datareg)++;
                if (csp->reg !=  - 1)
                //                        if (lvalue(csp->exp))
                //                           csp->seg = defseg(csp->exp->v.p[0]) ;
                //                        else
				if (!csp->seg)
				{
                    csp->seg = defseg(csp->exp);
					if (csp->seg)
						csp->reg = -1;
				}
            }

        }
        if (csp->reg !=  - 1)
        {
            if (lvalue(csp->exp) && !((SYM*)csp->exp->v.p[0]->v.p[0])->funcparm)
            {
                ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->inreg = TRUE;
                ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->value.i =  - csp
                    ->reg - (csp->size < 0 ?  - csp->size: csp->size) *256;
            }
            if (csp->reg < 16)
            {
                rmask = rmask | (1 << (15-csp->reg));
                mask = mask | (1 << csp->reg);
            }
            if (csp->reg < 32)
            {
                rmask = rmask | (1 << (23-csp->reg));
                mask = mask | (1 << (csp->reg - 8));
            }
            else
            {
                frmask = frmask | (1 << (39-csp->reg));
                fmask = fmask | (1 << (csp->reg - 32));
            }
        }
        csp = csp->next;
    }
    allocstack(); /* Allocate stack space for the local vars */
    floatstack_mode = 0; /* no space for floating point temps */
    if (currentfunc->intflag || currentfunc->faultflag)
    {
        mask = 0;
        rmask = 0;
        if (currentfunc->loadds)
            loadds();
        if (prm_farkeyword)
        {
            GenPush(ES + 24, am_dreg, 0);
            GenPush(FS + 24, am_dreg, 0);
            GenPush(GS + 24, am_dreg, 0);
        }
        gen_code(op_pushad, 0, 0);
    }
    if ((conscount || try_block_list || currentfunc->value.classdata.throwlist
        && currentfunc->value.classdata.throwlist->data) && prm_xcept)
    {
        xceptoffs = lc_maxauto += sizeof(XCEPTDATA);
    }
	if (prm_debug)
	{
        rmask = rmask | (1 << (15-EBX));
        mask = mask | (1 << EBX);
        rmask = rmask | (1 << (15-ESI-4));
        mask = mask | (1 << (ESI+4));
        rmask = rmask | (1 << (15-EDI-4));
        mask = mask | (1 << (EDI+4));
	}
    if (prm_cplusplus && prm_xcept || (funcfloat || lc_maxauto || currentfunc
        ->tp->lst.head && currentfunc->tp->lst.head != (SYM*) - 1)
         || (currentfunc->value.classdata.cppflags &PF_MEMBER) && !(currentfunc
             ->value.classdata.cppflags &PF_STATIC)
     || !prm_smartframes || !stackframeoff)
    {
        /* enter is *really* inefficient so we will not use it */
        if (!currentfunc->intflag)
            gen_codes(op_push, 4, makedreg(EBP), 0);
        gen_codes(op_mov, 4, makedreg(EBP), makedreg(ESP));
        if (lc_maxauto)
            gen_code(op_sub, makedreg(ESP), make_immed(lc_maxauto));
        // FIXME ... could auto-alloc an FP value when no frame!
        frame_ins = peep_tail;
    }
    else
        frame_ins = 0;
    if (mask != 0)
        PushRegs(rmask);
    save_mask = mask;
    if (fmask != 0)
        fsave_mask = fmask;
    if (currentfunc->loadds && !currentfunc->intflag)
    {
        loadds();

    }
    if (prm_stackcheck && lc_maxauto)
    {
        AMODE *ap1;
        ap = set_symbol("__stackerror", 1);
        ap1 = set_symbol("__stackbottom", 0);
        ap1->mode = am_direct;
        gen_codes(op_cmp, 4, makedreg(ESP), ap1);
        gen_codes(op_jb, 0, ap, 0);
    }
    AddProfilerData();
    if ((conscount || try_block_list || currentfunc->value.classdata.throwlist
        && currentfunc->value.classdata.throwlist->data) && prm_xcept)
    {
        currentfunc->value.classdata.conslabel = nextlabel++;
        currentfunc->value.classdata.destlabel = nextlabel++;
        gen_codes(op_mov, 4, makedreg(EAX), make_label(nextlabel - 2));
        call_library("__InitExceptBlock");
        gen_label(nextlabel - 1);
    }
}