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;