Processing Unary Sign Operators
This procedure processes unary plus or minus before a factor. Plus is skipped while minus changes the sign if expression is integer, extended or real.
Procedure ProcessUnaryMinus_Plus;
Var LastToken: TToken;
Overflow: Boolean;
TempInteger: LongInt;
TempIntegerTypeSet: TIntegerTypeSet;
begin
LastToken := Token;
CheckPlusMinusAndGetNextToken;
ProcessFactor;
If LastToken <> Token_Minus then Exit;
Case TypeDefPtr^.BaseType of
btInteger: begin
If Location = elConstant then
begin
Overflow := False;
TempInteger := 0 - Value.LongInt;
Asm
JNO @1
INC Overflow
@1:
end;
CheckOrdinalOverflowAndStore (TempInteger, Overflow);
Exit;
end;
SetLowestCommonIntegerType ([itSigned, it16Bit], DataType, TempIntegerTypeSet);
ExtendInteger (TempIntegerTypeSet);
Calculate;
LoadExpressionToRegisters (urAX);
If not (it32Bit in DataType) then GenerateInstruction_TwoBytes ($F7, $D8) { NEG AX }
else GenerateCode_NEG_LongInt;
GenerateOverflowCheckingCode (Self);
EndIntermediateCodeSubroutine;
end;
btExtended: begin
If Location <> elConstant then
begin
ConvertRealToExtended;
LoadExpressionToFPU;
Calculate;
ModifyAndSroreFPUInstructionForFixup ($E0D9); { FCHS }
EndIntermediateCodeSubroutine;
end else Value.Extended := - Value.Extended;
end;
btReal: begin
If Instructions80x87 in StatementCompilerSwitches then
begin
ConvertRealToExtended;
LoadExpressionToFPU;
Calculate;
ModifyAndSroreFPUInstructionForFixup ($E0D9); { FCHS }
EndIntermediateCodeSubroutine;
Exit;
end;
Calculate;
LoadRealExpressionToRegisterSet (rAX_BX_DX);
GenerateInstruction_TwoBytes ($08, $C0); { OR AL, AL }
GenerateInstruction_TwoBytes ($74, $03); { JE $ + 5 }
GenerateInstruction_TwoBytes ($80, $F6); { XOR DH, 80 }
GenerateInstruction_Byte ($80);
EndIntermediateCodeSubroutine;
end;
else Error (OperandTypesDoNotMatchOperator);
end;
end;