System Function Abs
This procedure processes system function Abs
. It simply converts negative numbers to positive.
Procedure Func_Abs; Far;
Var TempInteger: LongInt;
Overflow: Boolean;
CommonType: TIntegerTypeSet;
begin
Expression^.ExpectIntegerOrFloatingPointExpressionInParentheses;
With Expression^ do
begin
If TypeDefPtr^.BaseType = btInteger then
begin
If Location = elConstant then
begin
If Value.W12 and $8000 <> 0 then
begin
Overflow := False;
TempInteger := 0 - Value.LongInt;
Asm
JNO @1
INC Overflow
@1:
end;
Expression^.CheckOrdinalOverflowAndStore (TempInteger, Overflow);
end;
Exit;
end;
SetLowestCommonIntegerType ([itSigned, it16Bit], DataType, CommonType);
Expression^.ExtendInteger (CommonType);
Expression^.Calculate;
Expression^.LoadExpressionToRegisters (urAX);
If it16Bit in DataType then
begin
GenerateInstruction_TwoBytes ($09, $D2); { OR DX, DX }
GenerateInstruction_TwoBytes ($79, $07); { JNS $ + 9 }
GenerateCode_NEG_LongInt;
end else begin
GenerateInstruction_Byte ($99); { CWD }
GenerateInstruction_TwoBytes ($31, $D0); { XOR AX, DX }
GenerateInstruction_TwoBytes ($29, $D0); { SUB AX, DX }
end;
GenerateOverflowCheckingCode (Expression^);
Expression^.EndIntermediateCodeSubroutine;
Exit;
end;
If TypeDefPtr^.BaseType = btExtended then
begin
If Location = elConstant then
begin
Value.As10Bytes [9] := Value.As10Bytes [9] and $7F;
Exit;
end;
Expression^.ConvertRealToExtended;
Expression^.LoadExpressionToFPU;
Expression^.Calculate;
ModifyAndSroreFPUInstructionForFixup ($E1D9); { FABS }
Expression^.EndIntermediateCodeSubroutine;
Exit;
end;
If Instructions80x87 in StatementCompilerSwitches then
begin
Expression^.ConvertRealToExtended;
Expression^.LoadExpressionToFPU;
Expression^.Calculate;
ModifyAndSroreFPUInstructionForFixup ($E1D9); { FABS }
Expression^.EndIntermediateCodeSubroutine;
Exit;
end;
Expression^.Calculate;
Expression^.LoadRealExpressionToRegisterSet (rAX_BX_DX);
GenerateInstruction_TwoBytes ($80, $E6);
GenerateInstruction_Byte ($7F);
Expression^.EndIntermediateCodeSubroutine;
end;
end;