Ignore:
Timestamp:
May 7, 2019, 5:58:20 PM (6 years ago)
Author:
chronos
Message:
  • Added: More instruction implemented for pascal code generator.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu4/UCompilerPascal.pas

    r186 r187  
    66
    77uses
    8   Classes, SysUtils, UInstructionReader, UOpcode, UCpu;
     8  Classes, SysUtils, UInstructionReader, UOpcode, UCpu, strutils;
    99
    1010type
     
    1616    OpcodeDefs: TOpcodeDefs;
    1717    Instructions: array[TOpcode] of TInstructionEvent;
     18    Indent: Integer;
     19    Labels: TStringList;
    1820    procedure InstConvert;
    1921    procedure InstNop;
     
    9193begin
    9294  R := Reader.Read8;
    93   AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize));
     95  AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) + ';');
    9496end;
    9597
     
    100102procedure TCompilerPascal.InstHalt;
    101103begin
    102   AddLine('Exit');
     104  AddLine('Exit;');
    103105end;
    104106
     
    109111  R1 := Reader.Read8;
    110112  R2 := Reader.Read8;
    111   AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize));
     113  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) + ';');
    112114end;
    113115
     
    117119begin
    118120  R := Reader.Read8;
    119   AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntToStr(Reader.ReadData));
     121  AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntToHexEx(Reader.ReadData, -1, '$') + ';');
    120122end;
    121123
    122124procedure TCompilerPascal.InstJump;
    123125begin
    124   Reader.ReadAddress;
    125   // TODO
     126  AddLine('GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    126127end;
    127128
    128129procedure TCompilerPascal.InstJumpZero;
    129130begin
    130   Reader.ReadAddress;
    131   // TODO
     131  AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    132132end;
    133133
    134134procedure TCompilerPascal.InstJumpNotZero;
    135135begin
    136   Reader.ReadAddress;
    137   // TODO
     136  AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    138137end;
    139138
    140139procedure TCompilerPascal.InstJumpRel;
    141 begin
    142   Reader.ReadAddressSigned;
    143   // TODO
     140var
     141  Addr: TAddressSigned;
     142begin
     143  Addr := Reader.ReadAddressSigned;
     144  AddLine('GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    144145end;
    145146
    146147procedure TCompilerPascal.InstJumpRelZero;
    147 begin
    148   Reader.ReadAddressSigned;
    149   // TODO
     148var
     149  Addr: TAddressSigned;
     150begin
     151  Addr := Reader.ReadAddressSigned;
     152  AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    150153end;
    151154
    152155procedure TCompilerPascal.InstJumpRelNotZero;
    153 begin
    154   Reader.ReadAddressSigned;
    155   // TODO
     156var
     157  Addr: TAddressSigned;
     158begin
     159  Addr := Reader.ReadAddressSigned;
     160  AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    156161end;
    157162
     
    161166begin
    162167  R := Reader.Read8;
    163   AddLine('Z := ' + GetRegister(R, Reader.DataSize) + ' = 0');
     168  AddLine('Zero := ' + GetRegister(R, Reader.DataSize) + ' = 0;');
    164169end;
    165170
     
    169174begin
    170175  R := Reader.Read8;
    171   AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize));
     176  AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize) + ';');
    172177end;
    173178
     
    177182begin
    178183  R := Reader.Read8;
    179   AddLine(GetRegister(R, Reader.DataSize) + ' := 0');
     184  AddLine(GetRegister(R, Reader.DataSize) + ' := 0;');
    180185end;
    181186
     
    187192  R2 := Reader.Read8;
    188193  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' +
    189     GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize));
     194    GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize) + ';');
    190195end;
    191196
     
    197202  R2 := Reader.Read8;
    198203  AddLine(GetMemory(GetRegister(R1, Reader.AddrSize), Reader.AddrSize) + ' := ' +
    199     GetRegister(R2, Reader.DataSize));
     204    GetRegister(R2, Reader.DataSize) + ';');
    200205end;
    201206
     
    206211  R1 := Reader.Read8;
    207212  R2 := Reader.Read8;
    208   // TODO
     213  AddLine('Temp := ' + GetRegister(R1, Reader.DataSize) + ';');
     214  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) + ';');
     215  AddLine(GetRegister(R2, Reader.DataSize) + ' := Temp;');
    209216end;
    210217
     
    214221begin
    215222  R := Reader.Read8;
    216   AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');' + LineEnding +
    217     GetMemory('SP', Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize));
     223  AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
     224  AddLine(GetMemory('SP', Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) + ';');
    218225end;
    219226
     
    223230begin
    224231  R := Reader.Read8;
    225   AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + LineEnding +
    226     'Inc(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
     232  AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + ';');
     233  AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
    227234end;
    228235
    229236procedure TCompilerPascal.InstCall;
    230 begin
    231   Reader.ReadAddress;
    232   // TODO
     237var
     238  Addr: QWord;
     239begin
     240  Addr := Reader.ReadAddress;
     241  AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.AddrSize]) + ');');
     242  AddLine(GetMemory('SP', Reader.AddrSize) + ' := ' + IntToStr(Reader.IP) + ';');
     243  AddLine('GotoAddr(@L' + IntToStr(Addr) + ');');
    233244end;
    234245
    235246procedure TCompilerPascal.InstRet;
    236247begin
    237   // TODO
     248  AddLine('TempAddr := Pointer(' + GetMemory('SP', Reader.AddrSize) + ');');
     249  AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.AddrSize]) + ');');
     250  AddLine('GotoAddr(TempAddr);');
    238251end;
    239252
     
    277290
    278291procedure TCompilerPascal.InstMul;
    279 begin
    280 
     292var
     293  R1, R2: Byte;
     294begin
     295  R1 := Reader.Read8;
     296  R2 := Reader.Read8;
     297  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     298    ' * ' + GetRegister(R2, Reader.DataSize));
    281299end;
    282300
    283301procedure TCompilerPascal.InstDiv;
    284 begin
    285 
     302var
     303  R1, R2: Byte;
     304begin
     305  R1 := Reader.Read8;
     306  R2 := Reader.Read8;
     307  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     308    ' div ' + GetRegister(R2, Reader.DataSize));
    286309end;
    287310
    288311procedure TCompilerPascal.InstMod;
    289 begin
    290 
     312var
     313  R1, R2: Byte;
     314begin
     315  R1 := Reader.Read8;
     316  R2 := Reader.Read8;
     317  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     318    ' mod ' + GetRegister(R2, Reader.DataSize));
    291319end;
    292320
     
    296324begin
    297325  R := Reader.Read8;
    298   AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ')');
     326  AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ');');
    299327end;
    300328
     
    304332begin
    305333  R := Reader.Read8;
    306   AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ')');
     334  AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ');');
    307335end;
    308336
     
    377405procedure TCompilerPascal.InstLddr;
    378406begin
    379 
     407  // TODO
    380408end;
    381409
    382410procedure TCompilerPascal.InstLdir;
    383411begin
    384 
     412  // TODO
    385413end;
    386414
     
    410438
    411439procedure TCompilerPascal.InstDataSize;
    412 begin
    413   Reader.DataSizeBase := TBitWidth(Reader.Read8);
    414   Reader.DataSize := Reader.DataSizeBase;
     440var
     441  BitWidth: Byte;
     442begin
     443  BitWidth := Reader.Read8;
     444  if (BitWidth <> 0) and (BitWidth <= Byte(High(TBitWidth))) then begin
     445    Reader.DataSizeBase := TBitWidth(BitWidth);
     446    Reader.DataSize := Reader.DataSizeBase;
     447  end;
    415448end;
    416449
     
    440473
    441474procedure TCompilerPascal.InstAddrSize;
    442 begin
    443   Reader.AddrSizeBase := TBitWidth(Reader.Read8);
    444   Reader.AddrSize := Reader.AddrSizeBase;
     475var
     476  BitWidth: Byte;
     477begin
     478  BitWidth := Reader.Read8;
     479  if (BitWidth <> 0) and (BitWidth <= Byte(High(TBitWidth))) then begin
     480    Reader.AddrSizeBase := TBitWidth(BitWidth);
     481    Reader.AddrSize := Reader.AddrSizeBase;
     482  end; // TODO error reporting
    445483end;
    446484
     
    500538procedure TCompilerPascal.AddLine(Text: string);
    501539begin
    502   Output := Output + '  ' + Text + ';' + LineEnding;
     540  Output := Output + DupeString('  ', Indent) + Text + LineEnding;
    503541end;
    504542
    505543function TCompilerPascal.GetRegister(Index: Byte; BitWidth: TBitWidth): string;
    506544begin
    507   Result := 'Registers[' + IntToStr(Index) + ']' + BitWidthSuffix[BitWidth];
     545  Result := 'R' + IntToStr(Index) + BitWidthSuffix[BitWidth];
    508546end;
    509547
     
    517555  Opcode: Byte;
    518556  MemorySize: QWord;
     557  OutputBody: string;
     558  LabelsText: string;
     559  LabelAddr: QWord;
     560  I: Integer;
    519561begin
    520562  Reader.Init;
    521563  MemorySize := MemSize(Reader.Cpu.Memory);
    522   Output :=
    523     'type' + LineEnding +
    524     '  TBitWidth = (bwNone, bw8, bw16, bw32, bw64);' + LineEnding +
    525     '  TRegister = record' + LineEnding +
    526     '  case TBitWidth of' + LineEnding +
    527     '    bw8: (B: Byte);' + LineEnding +
    528     '    bw16: (W: Word);' + LineEnding +
    529     '    bw32: (D: DWord);' + LineEnding +
    530     '    bw64: (Q: QWord);' + LineEnding +
    531     '  end;' + LineEnding +
    532     'var' + LineEnding +
    533     '  Memory: Pointer;' + LineEnding +
    534     '  Registers: array[0..' + IntToStr(High(Reader.Cpu.Registers)) + '] of TRegister;' + LineEnding +
    535     '  SP: QWord;' + LineEnding +
    536     '  Zero: Boolean;' + LineEnding +
    537     'begin' + LineEnding +
    538     '  Memory := GetMem(' + IntToStr(MemorySize) + ');' + LineEnding;
     564  AddLine('begin');
     565  AddLine('  SP := ' + IntToStr(MemorySize) + ';');
     566  AddLine('  Memory := GetMem(' + IntToStr(MemorySize) + ');');
     567  Inc(Indent);
    539568  while Reader.IP < MemorySize do begin
    540569    Reader.Prefix := False;
     570    LabelAddr := Reader.IP;
    541571    Opcode := Reader.Read8;
    542572    if Opcode <= Integer(High(TOpcode)) then begin
     573      AddLine('L' + IntToStr(LabelAddr) + ':');
     574      Labels.Add('L' + IntToStr(LabelAddr));
    543575      if Opcode < Length(Instructions) then begin
    544576      if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)]
     
    552584    end;
    553585  end;
    554   Output := Output + 'end.' + LineEnding;
     586  Dec(Indent);
     587  AddLine('end.');
     588  OutputBody := Output;
     589
     590  Output := '';
     591  AddLine('type');
     592  AddLine('  TBitWidth = (bwNone, bw8, bw16, bw32, bw64);');
     593  AddLine('  TRegister = record');
     594  AddLine('  case TBitWidth of');
     595  AddLine('    bw8: (B: Byte);');
     596  AddLine('    bw16: (W: Word);');
     597  AddLine('    bw32: (D: DWord);');
     598  AddLine('    bw64: (Q: QWord);');
     599  AddLine('  end;');
     600  AddLine('var');
     601  AddLine('  Memory: Pointer;');
     602  for I := 0 to High(Reader.Cpu.Registers) do
     603    AddLine('  R' + IntToStr(I) + ': TRegister;');
     604  AddLine('  SP: QWord;');
     605  AddLine('  Zero: Boolean;');
     606  AddLine('  Temp: QWord;');
     607  AddLine('  TempAddr: Pointer;');
     608  AddLine('');
     609  AddLine('procedure GotoAddr(P: Pointer); inline; assembler;');
     610  AddLine('asm');
     611  AddLine('  jmp P;');
     612  AddLine('end;');
     613  AddLine('');
     614  LabelsText := '';
     615  for I := 0 to Labels.Count - 1 do begin
     616    if I > 0 then LabelsText := LabelsText + ', ';
     617    LabelsText := LabelsText + Labels[I];
     618  end;
     619  AddLine('label ' + LabelsText + ';');
     620  Output := Output + OutputBody;
    555621end;
    556622
     
    559625  OpcodeDefs := TOpcodeDefs.Create;
    560626  Reader := TInstructionReader.Create;
     627  Labels := TStringList.Create;
    561628  InitInstructions;
    562629end;
     
    566633  FreeAndNil(Reader);
    567634  FreeAndNil(OpcodeDefs);
     635  FreeAndNil(Labels);
    568636  inherited Destroy;
    569637end;
Note: See TracChangeset for help on using the changeset viewer.