Press enter to see results or esc to cancel.

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;