Real Operations
For Real
operations code is always generated. This procedure generates code for operations on Real
values. If 80×87 instructions are enabled, it converts both expressions to Extended
and generates FPU code otherwise it generates code to call system function.
Procedure GenerateCodeForRealOperations;
begin
If Instructions80x87 in StatementCompilerSwitches then
begin
LeftExpression.ConvertRealToExtended;
RightExpression.ConvertRealToExtended;
GenerateCodeForExtendedOperations;
Exit;
end;
Case Operation of
Calc_IsEqual..Calc_IsLowerOrEqual,
Calc_Add,
Calc_Multiply: If (RightExpression.UsedRegisters <> []) and (LeftExpression.UsedRegisters = []) then
ExchangeLeftAndRightExpression;
end;
Case RightExpression.UsedRegisters = [] of
True: begin
LeftExpression.Calculate;
LeftExpression.LoadRealExpressionToRegisterSet (rAX_BX_DX);
RightExpression.Calculate;
RightExpression.LoadRealExpressionToRegisterSet (rCX_SI_DI);
end;
else begin
RightExpression.Calculate;
RightExpression.LoadRealExpressionToRegisterSet (rAX_BX_DX);
GenerateInstruction_TwoBytes (PUSH_DX, PUSH_BX);
GenerateInstruction_Byte (PUSH_AX);
LeftExpression.Calculate;
LeftExpression.LoadRealExpressionToRegisterSet (rAX_BX_DX);
GenerateInstruction_Byte (POP_CX);
GenerateInstruction_TwoBytes (POP_SI, POP_DI);
end;
end;
Case Operation of
Calc_Add: GenerateInstruction_CALL_FAR (SysProc_RAdd);
Calc_Subtract: GenerateInstruction_CALL_FAR (SysProc_RSub);
Calc_Multiply: GenerateInstruction_CALL_FAR (SysProc_RMul);
Calc_Divide: GenerateInstruction_CALL_FAR (SysProc_RDiv);
else begin
GenerateInstruction_CALL_FAR (SysProc_RCmp);
LeftExpression.EndIntermediateCodeSubroutine;
LeftExpression.SetExpressionToBooleanJump (UnsignedConditionalJumpOpCode [Operation]);
Exit;
end;
end;
LeftExpression.EndIntermediateCodeSubroutine;
end;