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;
 
 
 
© 2017 Turbo Pascal | Privacy Policy