Press enter to see results or esc to cancel.

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;