示例#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 {
示例#2
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;
}