Press enter to see results or esc to cancel.

System Functions Succ and Pred

This procedure processes system functions Succ and Pred.

Procedure Func_Succ_Pred; Far;
Type POpCodes = ^TOpCodes;
     TOpCodes = Array [0..10] of Byte;
Const PredOpCodes: TOpCodes = (
        $FE, $C8,         { DEC   AL    }
        $2C, $01,         { SUB   AL, 1 }
        $48,              { DEC   AX    }
        $2D, $01, $00,    { SUB   AX, 1 }
        $83, $DA, $00);   { SBB   DX, 0 }

      SuccOpCodes: TOpCodes = (
        $FE, $C0,         { INC   AL    }
        $04, $01,         { ADD   AL, 1 }
        $40,              { INC   AX    }
        $05, $01, $00,    { ADD   AX, 1 }
        $83, $D2, $00);   { ADC   DX, 0 }

      OpCodes: Array [0..4, 0..1] of Byte = (
        (2, 0),
        (2, 2),
        (1, 4),
        (3, 5),
        (6, 5));

      Increment: Array [0..1] of ShortInt = (- 1, 1);

Var TempInt: LongInt;
    OverFlow: Boolean;
    StepArray: POpCodes;
    N, Index: Byte;
begin
  Case FuncParameter of
    0: StepArray := @PredOpCodes;
    1: StepArray := @SuccOpCodes;
  end;
  Expression^.ExpectOrdinalExpressionInParentheses;
  If Expression^.Location = elConstant then
    begin
      Overflow := False;
      TempInt := Expression^.Value.LongInt + Increment [FuncParameter];
      Asm
        JNO   @1
        INC   Overflow
    @1:
      end;
      Expression^.CheckOrdinalOverflowAndStore (TempInt, Overflow);
      Exit;
    end;
  If Expression^.Location = elPointerToMemory then
    begin
      If not (efSegment in Expression^.LocationData.Flags) then
        begin
          Inc (Expression^.Value.Integer, Increment [FuncParameter]);
          Exit;
        end;
      Expression^.LoadPointerToMemoryTo_DX_AX;
    end;
  Expression^.Calculate;
  Expression^.LoadExpressionToRegisters (urAX);
  Index := 0;
  If it16Bit in Expression^.DataType then
    begin
      Index := 2;
      If it32Bit in Expression^.DataType then Index := 4;
    end;
  If (OverflowChecking in StatementCompilerSwitches) and (itUnsigned in Expression^.DataType) then Inc (Index);
  For N := OpCodes [Index, 1] to OpCodes [Index, 1] + OpCodes [Index, 0] - 1 do GenerateInstruction_Byte (StepArray^ [N]);
  GenerateOverflowCheckingCode (Expression^);
  Expression^.EndIntermediateCodeSubroutine;
end;