Press enter to see results or esc to cancel.

Loading Expression To Registers

Loading an expression into registers is a very common task in Turbo Pascal compiler. These two functions take care for this. They generate instructions to load the expression regardless where it is located.

Procedure TExpression.LoadExpressionToRegisters (Register: TUsedRegister);
begin
  LoadExpressionToRegister (Ord (Register));
  If it32Bit in DataType then
    begin
      SwitchBetweenLoWordAndHiWord (2);
      LoadExpressionToRegister (Ord (Register) + 2);
      Include (UsedRegisters, Succ (Succ(Register)));
    end ;
  Include (UsedRegisters, Register);
  Location := elRegister;
  LocationData.Register := Ord (Register);
end;

Procedure TExpression.LoadExpressionToRegister (Register: Byte);
begin
  Case Location of
    elMemory: If (Register = rACC) and (LocationData.Flags * [ofsDI, ofsBP] = []) then
                begin
                  GenerateSegmentOverride;
                  If not (it16Bit in DataType) then GenerateInstruction_Byte (MOV_AL_Mem)
                    else GenerateInstruction_Byte (MOV_AX_Mem);
                  GenerateOffsetReferenceForExpressionInMemory;
                end else GenerateInstruction_8_16_bit (MOV_AX_RegMem, Register shl 3);
    elRegister: If LocationData.Register <> Register then
                  GenerateInstruction_8_16_bit (MOV_AX_RegMem, Register shl 3);
    elPointerToMemory: begin
                         If efSegment in LocationData.Flags then
                           begin
                             If LocationData.Flags * SegmentMask <> [] then
                               GenerateInstruction_TwoBytes (
                                 MOV_RegMem_ES, modRegister or Register or ExpressionSegmentRegister) else
                                   GenerateInstructionWithSegment (MOV_16BitReg_Immediate or Register);
                           end else
                             If ofsBP in LocationData.Flags then
                               GenerateInstructionWithExpressionInMemOrReg (LEA, Register shl 3) else
                                 If ofsDI in LocationData.Flags then
                                   begin
                                     If (LocationData.Flags * [efRelocatable, segCS, segDS] <> []) or (Value.Offset <> 0) then
                                       GenerateInstructionWithExpressionInMemOrReg (LEA, Register shl 3) else
                                         GenerateInstruction_TwoBytes (MOV_16Bit_Mem_Reg,
                                                                       modRegister or rDI shl 3 or Register);
                                   end else
                                     If LocationData.Flags * [efRelocatable, segCS, segDS] = [] then
                                       GenerateInstruction_MOV_16BitReg_Immediate (Register, Value.Offset) else
                                         begin
                                           GenerateInstruction_Byte (MOV_16BitReg_Immediate or Register);
                                           GenerateOffsetReferenceForExpressionInMemory;
                                         end;
                       end;
    else If not (it16Bit in DataType) then GenerateInstruction_TwoBytes (MOV_8BitReg_Immediate or Register, Value.ShortInt)
           else GenerateInstruction_MOV_16BitReg_Immediate (Register, Value.Word);
  end;
end;

This procedure loads Real expression to register set. There are two sets of registers for real expressions: AX BX DX and CX SI DI.

Type TRealRegistersSet = (rAX_BX_DX, rCX_SI_DI);

Procedure TExpression.LoadRealExpressionToRegisterSet (RealRegistersSet: TRealRegistersSet);
Const RealRegisters: Array [TRealRegistersSet, 1..3] of Byte = (
        (rAX, rBX, rDX),
        (rCX, rSI, rDI));

  Procedure LoadRealExpressionToRegister (Reg: Byte);
  begin
    LoadExpressionToRegister (RealRegisters [RealRegistersSet, Reg]);
    Case Location of
      elMemory: Inc (Value.Offset, 2);
      else begin
             Value.Word := Value.W12;
             Value.W12 := Value.W14;
           end;
    end;
  end;

begin
  If Location <> elRegister then
    begin
      LoadRealExpressionToRegister (1);
      LoadRealExpressionToRegister (2);
      LoadRealExpressionToRegister (3);
      ES_DI_PointerDestroyed;
      Location := elRegister;
    end;
  UsedRegisters := [urBX, urDX, urCX, urAX];
end;