Integer Division
This procedure generates code for integer division with constant. Special code is generated if divisor is power of 2.
Procedure IntegerConstantDivision (Divisor: Word);
Var ShiftCount: Byte;
TempDivisor: Word;
DivisionOpCode: Byte;
begin
If Divisor = 1 then Exit;
If not (itSigned in RightExpression.DataType) then
begin
ShiftCount := 0;
TempDivisor := Divisor;
While (TempDivisor and $01) = 0 do
begin
Inc (ShiftCount);
TempDivisor := TempDivisor shr 1;
end;
If TempDivisor = 1 then
begin
If ShiftCount = 1 then
begin
GenerateInstruction_TwoBytes (ShiftRotateOperationsBy1_16Bit, SHR_AX);
Exit;
end;
If Instructions80286 in StatementCompilerSwitches then
begin
GenerateInstruction_TwoBytes (ShiftRotateOperationsByValue_16Bit, SHR_AX);
GenerateInstruction_Byte (ShiftCount);
Exit;
end;
If ShiftCount = 2 then
begin
GenerateInstruction_TwoBytes (ShiftRotateOperationsBy1_16Bit, SHR_AX);
GenerateInstruction_TwoBytes (ShiftRotateOperationsBy1_16Bit, SHR_AX);
Exit;
end;
Include (RightExpression.UsedRegisters, urDX);
GenerateInstruction_TwoBytes (MOV_CL_Immediate, ShiftCount);
GenerateInstruction_TwoBytes (ShiftRotateOperationsByCL_16Bit, SHR_AX);
Exit;
end;
Case itUnsigned in RightExpression.DataType of
True: begin
GenerateInstruction_Word (XOR_DX_DX);
DivisionOpCode := DIV_CX;
end;
else begin
GenerateInstruction_Byte (CWD);
DivisionOpCode := IDIV_CX;
end;
end;
end else begin
GenerateInstruction_Byte (CWD);
DivisionOpCode := IDIV_CX;
end;
GenerateInstruction_Byte (MOV_CX_Immediate);
GenerateInstruction_Word (Divisor);
GenerateInstruction_TwoBytes (Unary_16Bit_Operations, DivisionOpCode);
RightExpression.UsedRegisters := RightExpression.UsedRegisters + [urDX, urCX];
end;
This procedure generates general code for integer division.
Procedure GeneralIntegerDivision;
Var OpCode: WordRec;
begin
OpCode.Word := IntegerOpCodes [Operation].Word;
If itUnsigned in RightExpression.DataType then
begin
GenerateInstruction_Word (XOR_DX_DX);
OpCode.ByteH := DIV_CX;
end else GenerateInstruction_Byte (CWD);
GenerateCodeForDivisionOrMultiplication (OpCode.ByteL, OpCode.ByteH);
end;
Procedure GenerateCodeForDivisionOrMultiplication (OpCode0, OpCode1: Byte);
begin
If RightExpression.Location = elConstant then
RightExpression.LoadExpressionToRegisters (urCX);
RightExpression.GenerateInstructionWithExpressionInMemOrReg (OpCode0, OpCode1);
Include (RightExpression.UsedRegisters, urDX);
end;