Esempio n. 1
0
TType *TCodeGenerator::EmitSimpleExpression(void)
{
    TType      *pOperandType;      // ptr to operand's type
    TType      *pResultType;       // ptr to result type
    TTokenCode  op;                // operator
    TTokenCode  unaryOp = tcPlus;  // unary operator

    //--Unary + or -
    if (TokenIn(token, tlUnaryOps)) {
	unaryOp = token;
	GetToken();
    }

    //--Emit code for the first term.
    pResultType = EmitTerm();

    //--If there was a unary operator, negate in integer value in ax
    //--with the neg instruction, or negate a real value in dx:ax
    //--by calling _FloatNegate.
    if (unaryOp == tcMinus) {
	if (pResultType->Base() == pIntegerType) Emit1(neg, Reg(ax))
	else if (pResultType == pRealType) {
	    EmitPushOperand(pResultType);
	    Emit1(call, NameLit(FLOAT_NEGATE));
	    Emit2(add,  Reg(sp), IntegerLit(4));
	}
    }

    //--Loop to execute subsequent additive operators and terms.
    while (TokenIn(token, tlAddOps)) {
	op = token;
	pResultType = pResultType->Base();
	EmitPushOperand(pResultType);

	GetToken();
	pOperandType = EmitTerm()->Base();

	//--Perform the operation, and push the resulting value
	//--onto the stack.
	if (op == tcOR) {

	    //--boolean OR boolean => boolean
	    //--ax = ax OR dx
	    Emit1(pop, Reg(dx));
	    Emit2(or,  Reg(ax), Reg(dx));
	    pResultType = pBooleanType;
	}
	else if ((pResultType  == pIntegerType) &&
		 (pOperandType == pIntegerType)) {

	    //--integer +|- integer => integer
	    Emit1(pop, Reg(dx));
	    if (op == tcPlus) Emit2(add, Reg(ax), Reg(dx))
	    else {
		Emit2(sub, Reg(dx), Reg(ax));
		Emit2(mov, Reg(ax), Reg(dx));
	    }
	    pResultType = pIntegerType;
	}
	else {
Esempio n. 2
0
jc_uint BackFillGotoStack(CJcGotoStack * pStack, CJcSegment* pCodeSegment, CJcGotoFillError *pError)
{
	CJcGoto* pGoto;
	jc_uint nSize, i, *pGotoAddr;
	CJcGotoTable* pTable = pStack->pGotoTable;
	if(!pTable)
		return 1;
	nSize = pTable->nCount;
	for(i=0; i<nSize; ++i)
	{
		pGoto = pTable->pGotoTable + i;
		pGotoAddr = (jc_uint*)SearchInHashTable(pTable->pLabelTable, pGoto->oLabelName.pStr);
		if(pGotoAddr)
			Emit1(pCodeSegment, jc_jmp, JC_UN, *pGotoAddr, pGoto->nInsAddr);
		else
		{
			pError->sFileName = pGoto->sFileName;
			pError->nLine = pGoto->nLine;
			pError->nCol = pGoto->nCol;
			pError->sLabel = pGoto->oLabelName.pStr;
			return 1;
		}
	}
	return 0;
}
Esempio n. 3
0
TType *TCodeGenerator::EmitArctanCosExpLnSinSqrtCall
(const TSymtabNode *pRoutineId)
{
    char *stdFuncName;

    GetToken();  // (
    GetToken();

    //--Evaluate the parameter, and convert an integer value to
    //--real if necessary.
    TType *pParmType = EmitExpression()->Base();
    if (pParmType == pIntegerType) {
        Emit1(push, Reg(ax));
        Emit1(call, NameLit(FLOAT_CONVERT));
        Emit2(add,  Reg(sp), IntegerLit(2));
    }

    EmitPushOperand(pRealType);

    switch (pRoutineId->defn.routine.which) {
    case rcArctan:
        stdFuncName = STD_ARCTAN;
        break;
    case rcCos:
        stdFuncName = STD_COS;
        break;
    case rcExp:
        stdFuncName = STD_EXP;
        break;
    case rcLn:
        stdFuncName = STD_LN;
        break;
    case rcSin:
        stdFuncName = STD_SIN;
        break;
    case rcSqrt:
        stdFuncName = STD_SQRT;
        break;
    }

    Emit1(call, NameLit(stdFuncName));
    Emit2(add,  Reg(sp), IntegerLit(4));

    GetToken();  // token after )
    return pRealType;
}
Esempio n. 4
0
TType *TCodeGenerator::EmitEofEolnCall(const TSymtabNode *pRoutineId)
{
    Emit1(call, NameLit(pRoutineId->defn.routine.which == rcEof
                        ? STD_EOF
                        : STD_EOLN));

    GetToken();  // token after function name
    return pBooleanType;
}
Esempio n. 5
0
File: vm_x86.cpp Progetto: eakoli/vm
	vm_asm_t& Emit4(int v)
	{
		Emit1(v & 255);
		Emit1((v>>8)&255);
		Emit1((v>>16)&255);
		Emit1((v>>24)&255);

		return *this;
	}
Esempio n. 6
0
TType *TCodeGenerator::EmitAbsSqrCall(const TSymtabNode *pRoutineId)
{
    GetToken();  // (
    GetToken();

    TType *pParmType = EmitExpression()->Base();

    switch (pRoutineId->defn.routine.which) {

    case rcAbs:
        if (pParmType == pIntegerType) {
            int nonNegativeLabelIndex = ++asmLabelIndex;

            Emit2(cmp, Reg(ax), IntegerLit(0));
            Emit1(jge,
                  Label(STMT_LABEL_PREFIX, nonNegativeLabelIndex));
            Emit1(neg, Reg(ax));

            EmitStatementLabel(nonNegativeLabelIndex);
        }
        else {
            EmitPushOperand(pParmType);
            Emit1(call, NameLit(STD_ABS));
            Emit2(add,  Reg(sp), IntegerLit(4));
        }
        break;

    case rcSqr:
        if (pParmType == pIntegerType) {
            Emit2(mov,  Reg(dx), Reg(ax));
            Emit1(imul, Reg(dx));
        }
        else {
            EmitPushOperand(pParmType);
            EmitPushOperand(pParmType);
            Emit1(call, NameLit(FLOAT_MULTIPLY));
            Emit2(add,  Reg(sp), IntegerLit(8));
        }
        break;
    }

    GetToken();  // token after )
    return pParmType;
}
Esempio n. 7
0
TType *TCodeGenerator::EmitPredSuccCall(const TSymtabNode *pRoutineId)
{
    GetToken();  // (
    GetToken();

    TType *pParmType = EmitExpression();

    Emit1(pRoutineId->defn.routine.which == rcPred ? decr : incr,
          Reg(ax));

    GetToken();  // token after )
    return pParmType;
}
Esempio n. 8
0
TType *TCodeGenerator::EmitRoundTruncCall(const TSymtabNode *pRoutineId)
{
    GetToken();  // (
    GetToken();
    EmitExpression();

    EmitPushOperand(pRealType);
    Emit1(call, NameLit(pRoutineId->defn.routine.which == rcRound
                        ? STD_ROUND : STD_TRUNC));
    Emit2(add, Reg(sp), IntegerLit(4));

    GetToken();  // token after )
    return pIntegerType;
}
Esempio n. 9
0
static void EmitString( const char *string ) {
	int		c1, c2;
	int		v;

	while ( 1 ) {
		c1 = string[0];
		c2 = string[1];

		v = ( Hex( c1 ) << 4 ) | Hex( c2 );
		Emit1( v );

		if ( !string[2] ) {
			break;
		}
		string += 3;
	}
}
Esempio n. 10
0
File: vm_x86.cpp Progetto: eakoli/vm
	vm_asm_t& Emit( const char* s )
	{
		int c1,c2;
		int c;
		while( true ) {
			c1 = s[0];
			c2 = s[1];

			c = (Hex(c1) << 4) | Hex(c2);

			Emit1(c);

			if( !s[2] )
				break;
			s+=3;
		}

		return *this;
	}
Esempio n. 11
0
TType *TCodeGenerator::EmitReadReadlnCall(const TSymtabNode *pRoutineId)
{
    //--Actual parameters are optional for readln.
    GetToken();
    if (token == tcLParen) {

        //--Loop to emit code to read each parameter value.
        do {
            //--Variable
            GetToken();
            TSymtabNode *pVarId   = pNode;
            TType       *pVarType = EmitVariable(pVarId, true)->Base();

            //--Read the value.
            if (pVarType == pIntegerType) {
                Emit1(call, NameLit(READ_INTEGER));
                Emit1(pop,  Reg(bx));
                Emit2(mov,  WordIndirect(bx), Reg(ax));
            }
            else if (pVarType == pRealType) {
                Emit1(call, NameLit(READ_REAL));
                Emit1(pop,  Reg(bx));
                Emit2(mov,  WordIndirect(bx), Reg(ax));
                Emit2(mov,  HighDWordIndirect(bx), Reg(dx));
            }
            else if (pVarType == pCharType) {
                Emit1(call, NameLit(READ_CHAR));
                Emit1(pop,  Reg(bx));
                Emit2(mov,  ByteIndirect(bx), Reg(al));
            }
        } while (token == tcComma);

        GetToken();  // token after )
    }

    //--Skip the rest of the input line if readln.
    if (pRoutineId->defn.routine.which == rcReadln) {
        Emit1(call, NameLit(READ_LINE));
    }

    return pDummyType;
}
Esempio n. 12
0
static void Emit4( int v ) {
	Emit1( v & 255 );
	Emit1( ( v >> 8 ) & 255 );
	Emit1( ( v >> 16 ) & 255 );
	Emit1( ( v >> 24 ) & 255 );
}
Esempio n. 13
0
static void Emit2( int v ) {
	Emit1( v & 255 );
	Emit1( ( v >> 8 ) & 255 );
}
Esempio n. 14
0
TType *TCodeGenerator::EmitExpression(void)
{
    TType        *pOperand1Type;  // ptr to first  operand's type
    TType        *pOperand2Type;  // ptr to second operand's type
    TType        *pResultType;    // ptr to result type
    TTokenCode    op;             // operator
    TInstruction  jumpOpcode;     // jump instruction opcode
    int           jumpLabelIndex; // assembly jump label index

    //--Emit code for the first simple expression.
    pResultType = EmitSimpleExpression();

    //--If we now see a relational operator,
    //--emit code for the second simple expression.
    if (TokenIn(token, tlRelOps)) {
	EmitPushOperand(pResultType);
	op            = token;
	pOperand1Type = pResultType->Base();

	GetToken();
	pOperand2Type = EmitSimpleExpression()->Base();

	//--Perform the operation, and push the resulting value
	//--onto the stack.
	if (   ((pOperand1Type == pIntegerType) &&
		(pOperand2Type == pIntegerType))
	    || ((pOperand1Type == pCharType) &&
		(pOperand2Type == pCharType))
	    || (pOperand1Type->form == fcEnum)) {

	    //--integer <op> integer
	    //--boolean <op> boolean
	    //--char    <op> char
	    //--enum    <op> enum
	    //--Compare dx (operand 1) to ax (operand 2).
	    Emit1(pop, Reg(dx));
	    Emit2(cmp, Reg(dx), Reg(ax));
	}
	else if ((pOperand1Type == pRealType) ||
		 (pOperand2Type == pRealType)) {

	    //--real    <op> real
	    //--real    <op> integer
	    //--integer <op> real
	    //--Convert the integer operand to real.
	    //--Call _FloatCompare to do the comparison, which
	    //--returns -1 (less), 0 (equal), or +1 (greater).
	    EmitPushOperand(pOperand2Type);
	    EmitPromoteToReal(pOperand1Type, pOperand2Type);

	    Emit1(call, NameLit(FLOAT_COMPARE));
	    Emit2(add,  Reg(sp), IntegerLit(8));
	    Emit2(cmp,  Reg(ax), IntegerLit(0));
	}
	else {

	    //--string <op> string
	    //--Compare the string pointed to by si (operand 1)
	    //--to the string pointed to by di (operand 2).
	    Emit1(pop, Reg(di));
	    Emit1(pop, Reg(si));
	    Emit2(mov, Reg(ax), Reg(ds));
	    Emit2(mov, Reg(es), Reg(ax));
	    Emit0(cld);
	    Emit2(mov, Reg(cx),
		       IntegerLit(pOperand1Type->array.elmtCount));
	    Emit0(repe_cmpsb);
	}

	Emit2(mov, Reg(ax), IntegerLit(1));  // default: load 1 

	switch (op) {
	    case tcLt:    jumpOpcode = jl;   break;
	    case tcLe:    jumpOpcode = jle;  break;
	    case tcEqual: jumpOpcode = je;   break;
	    case tcNe:    jumpOpcode = jne;  break;
	    case tcGe:    jumpOpcode = jge;  break;
	    case tcGt:    jumpOpcode = jg;   break;
	}

	jumpLabelIndex = ++asmLabelIndex;
	Emit1(jumpOpcode, Label(STMT_LABEL_PREFIX, jumpLabelIndex));

	Emit2(sub, Reg(ax), Reg(ax));     // load 0 if false
	EmitStatementLabel(jumpLabelIndex);

	pResultType = pBooleanType;
    }

    return pResultType;
}
Esempio n. 15
0
TType *TCodeGenerator::EmitWriteWritelnCall
(const TSymtabNode *pRoutineId)
{
    const int defaultFieldWidth = 10;
    const int defaultPrecision  =  2;

    //--Actual parameters are optional for writeln.
    GetToken();
    if (token == tcLParen) {

        //--Loop to emit code for each parameter value.
        do {
            //--<expr-1>
            GetToken();
            TType *pExprType = EmitExpression()->Base();

            //--Push the scalar value to be written onto the stack.
            //--A string value is already on the stack.
            if (pExprType->form != fcArray) {
                EmitPushOperand(pExprType);
            }

            if (token == tcColon) {

                //--Field width <expr-2>
                //--Push its value onto the stack.
                GetToken();
                EmitExpression();
                Emit1(push, Reg(ax));

                if (token == tcColon) {

                    //--Precision <expr-3>
                    //--Push its value onto the stack.
                    GetToken();
                    EmitExpression();
                    Emit1(push, Reg(ax));
                }
                else if (pExprType == pRealType) {

                    //--No precision: Push the default precision.
                    Emit2(mov, Reg(ax), IntegerLit(defaultPrecision));
                    Emit1(push, Reg(ax));
                }
            }
            else {

                //--No field width: Push the default field width and
                //--                the default precision.
                if (pExprType == pIntegerType) {
                    Emit2(mov,  Reg(ax), IntegerLit(defaultFieldWidth));
                    Emit1(push, Reg(ax));
                }
                else if (pExprType == pRealType) {
                    Emit2(mov,  Reg(ax), IntegerLit(defaultFieldWidth));
                    Emit1(push, Reg(ax));
                    Emit2(mov,  Reg(ax), IntegerLit(defaultPrecision));
                    Emit1(push, Reg(ax));
                }
                else {
                    Emit2(mov,  Reg(ax), IntegerLit(0));
                    Emit1(push, Reg(ax));
                }
            }

            //--Emit the code to write the value.
            if (pExprType == pIntegerType) {
                Emit1(call, NameLit(WRITE_INTEGER));
                Emit2(add,  Reg(sp), IntegerLit(4));
            }
            else if (pExprType == pRealType) {
                Emit1(call, NameLit(WRITE_REAL));
                Emit2(add,  Reg(sp), IntegerLit(8));
            }
            else if (pExprType == pBooleanType) {
                Emit1(call, NameLit(WRITE_BOOLEAN));
                Emit2(add,  Reg(sp), IntegerLit(4));
            }
            else if (pExprType == pCharType) {
                Emit1(call, NameLit(WRITE_CHAR));
                Emit2(add,  Reg(sp), IntegerLit(4));
            }
            else {      // string

                //--Push the string length onto the stack.
                Emit2(mov, Reg(ax),
                      IntegerLit(pExprType->array.elmtCount));

                Emit1(push, Reg(ax));
                Emit1(call, NameLit(WRITE_STRING));
                Emit2(add,  Reg(sp), IntegerLit(6));
            }

        } while (token == tcComma);

        GetToken();  // token after )
    }

    //--End the line if writeln.
    if (pRoutineId->defn.routine.which == rcWriteln) {
        Emit1(call, NameLit(WRITE_LINE));
    }

    return pDummyType;
}
Esempio n. 16
0
File: vm_x86.cpp Progetto: eakoli/vm
	vm_asm_t& Emit2(int v)
	{
		Emit1(v & 255);
		Emit1((v>>8)&255);
		return *this;
	}