LongInt Comparison
This procedure generates code to compare two LongInt
values. Again, for some special cases shorter code is generated.
Procedure GenerateCodeForLongIntComparisons;
Procedure GenerateShortCircuitLongIntComparisonJumps;
Const OpCodes: Array [Calc_IsEqual..Calc_IsLowerOrEqual, Boolean] of Byte = (
(JNE, 0),
( 0, JNE),
( JL, JG),
( JG, JL),
( JL, JG),
( JG, JL));
begin
If OpCodes [Operation, True] <> 0 then
GenerateCodeForNearJump (LongIntComparisonLastJumpToTrue, OpCodes [Operation, True]);
If OpCodes [Operation, False] <> 0 then
GenerateCodeForNearJump (LongIntComparisonLastJumpToFalse, OpCodes [Operation, False]);
end;
Procedure GeneralGenerateCodeForLongIntComparisons;
begin
LoadBothExpressionsToRegisters (LeftExpression, RightExpression, [urDX, urAX]);
RightExpression.SwitchBetweenLoWordAndHiWord (2);
RightExpression.GenerateArithmeticInstructionWith_DX (mod_CMP_rm);
GenerateShortCircuitLongIntComparisonJumps;
RightExpression.SwitchBetweenLoWordAndHiWord (- 2);
RightExpression.GenerateArithmeticInstructionWith_ACC (mod_CMP_rm);
end;
Procedure GenerateCodeForLongIntComparisonsWithConstant;
begin
If LeftExpression.Location = elMemory then
begin
LeftExpression.Calculate;
Inc (LeftExpression.Value.Word, 2);
LeftExpression.GenerateArithmeticInstructionWithImmediateValue (
RightExpression.Value.LongRec.WordH,
mod_CMP_rm);
GenerateShortCircuitLongIntComparisonJumps;
Dec (LeftExpression.Value.Word, 2);
LeftExpression.GenerateArithmeticInstructionWithImmediateValue (
RightExpression.Value.LongRec.WordL,
mod_CMP_rm);
end else GeneralGenerateCodeForLongIntComparisons;
end;
begin
LongIntComparisonLastJumpToTrue := 0;
LongIntComparisonLastJumpToFalse := 0;
If RightExpression.Location = elConstant then
begin
If RightExpression.Value.LongRec.Long <> 0 then GenerateCodeForLongIntComparisonsWithConstant
else begin
Case Operation of
Calc_IsEqual,
Calc_IsNotEqual: Case LeftExpression.Location of
elMemory:
begin
LeftExpression.Calculate;
Exclude (LeftExpression.DataType, it32Bit);
LeftExpression.LoadExpressionToRegister (rAX);
Inc (LeftExpression.Value.Word, 2);
LeftExpression.GenerateArithmeticInstructionWith_ACC (mod_OR_rm);
Include (LeftExpression.UsedRegisters, urAX);
end;
else begin
LeftExpression.Calculate;
GenerateInstruction_Word (OR_AX_DX);
end;
end;
else GenerateCodeForLongIntComparisonsWithConstant;
end;
end;
end else GeneralGenerateCodeForLongIntComparisons;
LeftExpression.SetExpressionToBooleanJump (UnsignedConditionalJumpOpCode [Operation]);
With LeftExpression do
begin
Value.LastJumpToTrue := LongIntComparisonLastJumpToTrue;
Value.LastJumpToFalse := LongIntComparisonLastJumpToFalse;
end;
end;