Changeset 187 for branches/virtualcpu4/UCompilerPascal.pas
- Timestamp:
- May 7, 2019, 5:58:20 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCompilerPascal.pas
r186 r187 6 6 7 7 uses 8 Classes, SysUtils, UInstructionReader, UOpcode, UCpu ;8 Classes, SysUtils, UInstructionReader, UOpcode, UCpu, strutils; 9 9 10 10 type … … 16 16 OpcodeDefs: TOpcodeDefs; 17 17 Instructions: array[TOpcode] of TInstructionEvent; 18 Indent: Integer; 19 Labels: TStringList; 18 20 procedure InstConvert; 19 21 procedure InstNop; … … 91 93 begin 92 94 R := Reader.Read8; 93 AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) );95 AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) + ';'); 94 96 end; 95 97 … … 100 102 procedure TCompilerPascal.InstHalt; 101 103 begin 102 AddLine('Exit ');104 AddLine('Exit;'); 103 105 end; 104 106 … … 109 111 R1 := Reader.Read8; 110 112 R2 := Reader.Read8; 111 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) );113 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) + ';'); 112 114 end; 113 115 … … 117 119 begin 118 120 R := Reader.Read8; 119 AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntTo Str(Reader.ReadData));121 AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntToHexEx(Reader.ReadData, -1, '$') + ';'); 120 122 end; 121 123 122 124 procedure TCompilerPascal.InstJump; 123 125 begin 124 Reader.ReadAddress; 125 // TODO 126 AddLine('GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');'); 126 127 end; 127 128 128 129 procedure TCompilerPascal.InstJumpZero; 129 130 begin 130 Reader.ReadAddress; 131 // TODO 131 AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');'); 132 132 end; 133 133 134 134 procedure TCompilerPascal.InstJumpNotZero; 135 135 begin 136 Reader.ReadAddress; 137 // TODO 136 AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');'); 138 137 end; 139 138 140 139 procedure TCompilerPascal.InstJumpRel; 141 begin 142 Reader.ReadAddressSigned; 143 // TODO 140 var 141 Addr: TAddressSigned; 142 begin 143 Addr := Reader.ReadAddressSigned; 144 AddLine('GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');'); 144 145 end; 145 146 146 147 procedure TCompilerPascal.InstJumpRelZero; 147 begin 148 Reader.ReadAddressSigned; 149 // TODO 148 var 149 Addr: TAddressSigned; 150 begin 151 Addr := Reader.ReadAddressSigned; 152 AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');'); 150 153 end; 151 154 152 155 procedure TCompilerPascal.InstJumpRelNotZero; 153 begin 154 Reader.ReadAddressSigned; 155 // TODO 156 var 157 Addr: TAddressSigned; 158 begin 159 Addr := Reader.ReadAddressSigned; 160 AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');'); 156 161 end; 157 162 … … 161 166 begin 162 167 R := Reader.Read8; 163 AddLine('Z := ' + GetRegister(R, Reader.DataSize) + ' = 0');168 AddLine('Zero := ' + GetRegister(R, Reader.DataSize) + ' = 0;'); 164 169 end; 165 170 … … 169 174 begin 170 175 R := Reader.Read8; 171 AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize) );176 AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize) + ';'); 172 177 end; 173 178 … … 177 182 begin 178 183 R := Reader.Read8; 179 AddLine(GetRegister(R, Reader.DataSize) + ' := 0 ');184 AddLine(GetRegister(R, Reader.DataSize) + ' := 0;'); 180 185 end; 181 186 … … 187 192 R2 := Reader.Read8; 188 193 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + 189 GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize) );194 GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize) + ';'); 190 195 end; 191 196 … … 197 202 R2 := Reader.Read8; 198 203 AddLine(GetMemory(GetRegister(R1, Reader.AddrSize), Reader.AddrSize) + ' := ' + 199 GetRegister(R2, Reader.DataSize) );204 GetRegister(R2, Reader.DataSize) + ';'); 200 205 end; 201 206 … … 206 211 R1 := Reader.Read8; 207 212 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;'); 209 216 end; 210 217 … … 214 221 begin 215 222 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) + ';'); 218 225 end; 219 226 … … 223 230 begin 224 231 R := Reader.Read8; 225 AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + LineEnding +226 232 AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + ';'); 233 AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');'); 227 234 end; 228 235 229 236 procedure TCompilerPascal.InstCall; 230 begin 231 Reader.ReadAddress; 232 // TODO 237 var 238 Addr: QWord; 239 begin 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) + ');'); 233 244 end; 234 245 235 246 procedure TCompilerPascal.InstRet; 236 247 begin 237 // TODO 248 AddLine('TempAddr := Pointer(' + GetMemory('SP', Reader.AddrSize) + ');'); 249 AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.AddrSize]) + ');'); 250 AddLine('GotoAddr(TempAddr);'); 238 251 end; 239 252 … … 277 290 278 291 procedure TCompilerPascal.InstMul; 279 begin 280 292 var 293 R1, R2: Byte; 294 begin 295 R1 := Reader.Read8; 296 R2 := Reader.Read8; 297 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) + 298 ' * ' + GetRegister(R2, Reader.DataSize)); 281 299 end; 282 300 283 301 procedure TCompilerPascal.InstDiv; 284 begin 285 302 var 303 R1, R2: Byte; 304 begin 305 R1 := Reader.Read8; 306 R2 := Reader.Read8; 307 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) + 308 ' div ' + GetRegister(R2, Reader.DataSize)); 286 309 end; 287 310 288 311 procedure TCompilerPascal.InstMod; 289 begin 290 312 var 313 R1, R2: Byte; 314 begin 315 R1 := Reader.Read8; 316 R2 := Reader.Read8; 317 AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) + 318 ' mod ' + GetRegister(R2, Reader.DataSize)); 291 319 end; 292 320 … … 296 324 begin 297 325 R := Reader.Read8; 298 AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ') ');326 AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ');'); 299 327 end; 300 328 … … 304 332 begin 305 333 R := Reader.Read8; 306 AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ') ');334 AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ');'); 307 335 end; 308 336 … … 377 405 procedure TCompilerPascal.InstLddr; 378 406 begin 379 407 // TODO 380 408 end; 381 409 382 410 procedure TCompilerPascal.InstLdir; 383 411 begin 384 412 // TODO 385 413 end; 386 414 … … 410 438 411 439 procedure TCompilerPascal.InstDataSize; 412 begin 413 Reader.DataSizeBase := TBitWidth(Reader.Read8); 414 Reader.DataSize := Reader.DataSizeBase; 440 var 441 BitWidth: Byte; 442 begin 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; 415 448 end; 416 449 … … 440 473 441 474 procedure TCompilerPascal.InstAddrSize; 442 begin 443 Reader.AddrSizeBase := TBitWidth(Reader.Read8); 444 Reader.AddrSize := Reader.AddrSizeBase; 475 var 476 BitWidth: Byte; 477 begin 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 445 483 end; 446 484 … … 500 538 procedure TCompilerPascal.AddLine(Text: string); 501 539 begin 502 Output := Output + ' ' + Text + ';'+ LineEnding;540 Output := Output + DupeString(' ', Indent) + Text + LineEnding; 503 541 end; 504 542 505 543 function TCompilerPascal.GetRegister(Index: Byte; BitWidth: TBitWidth): string; 506 544 begin 507 Result := 'R egisters[' + IntToStr(Index) + ']'+ BitWidthSuffix[BitWidth];545 Result := 'R' + IntToStr(Index) + BitWidthSuffix[BitWidth]; 508 546 end; 509 547 … … 517 555 Opcode: Byte; 518 556 MemorySize: QWord; 557 OutputBody: string; 558 LabelsText: string; 559 LabelAddr: QWord; 560 I: Integer; 519 561 begin 520 562 Reader.Init; 521 563 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); 539 568 while Reader.IP < MemorySize do begin 540 569 Reader.Prefix := False; 570 LabelAddr := Reader.IP; 541 571 Opcode := Reader.Read8; 542 572 if Opcode <= Integer(High(TOpcode)) then begin 573 AddLine('L' + IntToStr(LabelAddr) + ':'); 574 Labels.Add('L' + IntToStr(LabelAddr)); 543 575 if Opcode < Length(Instructions) then begin 544 576 if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)] … … 552 584 end; 553 585 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; 555 621 end; 556 622 … … 559 625 OpcodeDefs := TOpcodeDefs.Create; 560 626 Reader := TInstructionReader.Create; 627 Labels := TStringList.Create; 561 628 InitInstructions; 562 629 end; … … 566 633 FreeAndNil(Reader); 567 634 FreeAndNil(OpcodeDefs); 635 FreeAndNil(Labels); 568 636 inherited Destroy; 569 637 end;
Note:
See TracChangeset
for help on using the changeset viewer.