Changeset 153


Ignore:
Timestamp:
Apr 20, 2018, 10:56:29 PM (6 years ago)
Author:
chronos
Message:
  • Modified: Conditional jump/call divided to test instruction executed before jump.
  • Added: More opcode handling.
Location:
branches/virtualcpu2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu2/UFormMain.lfm

    r151 r153  
    77  ClientHeight = 732
    88  ClientWidth = 1504
    9   DesignTimePPI = 120
    109  OnCreate = FormCreate
    1110  OnDestroy = FormDestroy
    1211  OnShow = FormShow
    13   LCLVersion = '1.8.0.6'
     12  LCLVersion = '1.8.0.4'
    1413  object ButtonRun: TButton
    1514    Left = 32
  • branches/virtualcpu2/UFormMain.pas

    r151 r153  
    107107    AddCopyConst(Counter, 8);
    108108    AddCopyConst(Source, $30);
    109     AddCopyConst(Dest, $40);
     109    AddCopyConst(Dest, $60);
    110110
    111111    LoopAddr := Addr;
     
    115115    AddInc(Dest);
    116116    AddDec(Counter);
    117     AddJumpRelNotZero(Counter, LoopAddr - Addr);
     117    AddTestNotZero(Counter);
     118    AddJumpRelCond8(LoopAddr - Addr);
    118119    AddHalt;
    119120  end;
  • branches/virtualcpu2/UMachine.pas

    r152 r153  
    99
    1010type
     11 Int8    = ShortInt;
     12 Int16   = SmallInt;
     13 Int32   = Longint;
     14 PInt8 = ^Int8;
     15 PInt16 = ^Int16;
     16 PInt32 = ^Int32;
     17 UInt8   = Byte;
     18 UInt16  = Word;
     19 UInt32  = Cardinal;
     20 PUInt8   = ^UInt8;
     21 PUInt16  = ^UInt16;
     22 PUInt32  = ^UInt16;
     23
     24
    1125  //TAddrInt = Int8;
    1226  TAddrInt = Int16;
    1327  //TAddrInt = Int32;
    1428  //TAddrInt = Int64;
     29  PAddrInt = ^TAddrInt;
    1530  TDataInt = QWord;
    1631  //TDataInt = Int16;
     
    1934  PDataInt = ^TDataInt;
    2035
    21   TRegIndex = TAddrInt;
     36  TRegIndex = Byte;
    2237  TRegSize = Int8;
    2338
     
    4055    opPop,
    4156    // Skip
    42     opSkipZero,
    43     opSkipNotZero,
     57    opTestZero,
     58    opTestNotZero,
    4459    opSkipCarry,
    4560    opSkipNotCarray,
     
    4762    opCallRel,
    4863    opCallAbs,
     64    opCallRelCond,
     65    opCallAbsCond,
    4966    opRet,
    5067    // Jump
    5168    opJumpRel,
    5269    opJumpAbs,
     70    opJumpRelCond,
     71    opJumpAbsCond,
    5372    // Logical operations
    5473    opAnd,
     
    103122    procedure OpcodePop;
    104123    procedure OpcodePush;
     124    procedure OpcodePush8;
     125    procedure OpcodePush16;
     126    procedure OpcodePush32;
     127    procedure OpcodePush64;
    105128    procedure OpcodeLdir;
    106129    procedure OpcodeInc;
     
    110133    procedure OpcodeInc64;
    111134    procedure OpcodeDec;
    112     procedure OpcodeSkipNotZero;
    113     procedure OpcodeSkipZero;
     135    procedure OpcodeTestNotZero;
     136    procedure OpcodeTestZero;
    114137    procedure OpcodeJumpRel;
    115138    procedure OpcodeJumpAbs;
     139    procedure OpcodeJumpRelCond;
     140    procedure OpcodeJumpRelCond8;
     141    procedure OpcodeJumpAbsCond;
     142    procedure OpcodeCallRel;
     143    procedure OpcodeCallAbs;
     144    procedure OpcodeCallRelCond;
     145    procedure OpcodeCallAbsCond;
    116146    procedure OpcodeUnsupported;
     147    procedure OpcodeSetSize;
     148    procedure OpcodeSetSize8;
     149    procedure OpcodeSetSize16;
     150    procedure OpcodeSetSize32;
     151    procedure OpcodeSetSize64;
    117152    function ReadNext: TDataInt;
     153    function ReadNextS: TDataInt;
    118154    function ReadNext8: Byte;
    119155    function ReadNextS8: ShortInt;
     
    131167    SP: TAddrInt;
    132168    DataSize: TDataSize;
     169    BaseDataSize: TDataSize;
    133170    Terminated: Boolean;
    134     SkipNext: Boolean;
     171    Condition: Boolean;
    135172    procedure Run;
    136173    constructor Create;
     
    143180    Machine: TMachine;
    144181    procedure AddData(Data: TDataInt);
     182    procedure AddDataS(Data: Int64);
    145183    procedure AddData8(Data: Byte);
    146184    procedure AddDataS8(Data: ShortInt);
    147185    procedure AddCopyConst(Reg: TRegIndex; Value: TDataInt);
     186    procedure AddCopyConst8(Reg: TRegIndex; Value: UInt8);
    148187    procedure AddGetDataSize(Reg: TRegIndex);
    149188    procedure AddCopyFromMem(Reg, Src: TRegIndex);
     
    152191    procedure AddDec(Reg: TRegIndex);
    153192    procedure AddHalt;
    154     procedure AddJumpRelNotZero(Reg: TRegIndex; RelAddr: Integer);
     193    procedure AddTestNotZero(Reg: TRegIndex);
     194    procedure AddJumpRelCond(RelAddr: Integer);
     195    procedure AddJumpRelCond8(RelAddr: ShortInt);
    155196    constructor Create;
    156197  end;
    157198
    158199const
    159   DataSizeValue: array[TDataSize] of Byte = (SizeOf(TDataInt), SizeOf(Byte),
    160     SizeOf(Word), SizeOf(Cardinal), SizeOf(QWord));
     200  DataSizeValue: array[TDataSize] of Byte = (SizeOf(TDataInt), SizeOf(UInt8),
     201    SizeOf(UInt16), SizeOf(UInt32), SizeOf(UInt64));
    161202
    162203implementation
     
    203244  SetOpcode(opInc, OpcodeInc64, ds64);
    204245  SetOpcode(opDec, OpcodeDec);
    205   SetOpcode(opSkipZero, OpcodeSkipZero);
    206   SetOpcode(opSkipNotZero, OpcodeSkipNotZero);
     246  SetOpcode(opTestZero, OpcodeTestZero);
     247  SetOpcode(opTestNotZero, OpcodeTestNotZero);
    207248  SetOpcode(opJumpRel, OpcodeJumpRel);
    208249  SetOpcode(opJumpAbs, OpcodeJumpAbs);
     250  SetOpcode(opJumpRelCond, OpcodeJumpRelCond);
     251  SetOpcode(opJumpRelCond, OpcodeJumpRelCond8, ds8);
     252  SetOpcode(opJumpAbsCond, OpcodeJumpAbsCond);
     253  SetOpcode(opCallRel, OpcodeCAllRel);
     254  SetOpcode(opCallAbs, OpcodeCallAbs);
     255  SetOpcode(opCallRelCond, OpcodeCallRelCond);
     256  SetOpcode(opCallAbsCond, OpcodeCallAbsCond);
    209257  SetOpcode(opAdd, OpcodeAdd);
    210258  SetOpcode(opSub, OpcodeSub);
     
    214262  SetOpcode(opXor, OpcodeXor);
    215263  SetOpcode(opPush, OpcodePush);
     264  SetOpcode(opPush, OpcodePush8, ds8);
     265  SetOpcode(opPush, OpcodePush16, ds16);
     266  SetOpcode(opPush, OpcodePush32, ds32);
     267  SetOpcode(opPush, OpcodePush64, ds64);
    216268  SetOpcode(opPop, OpcodePop);
     269  SetOpcode(opSetSize8, OpcodeSetSize8);
    217270end;
    218271
     
    226279  if (Opcode <= High(Opcode)) then begin
    227280    OpcodeHandler := OpcodeTable[Opcode, DataSize];
    228     if not Assigned(OpcodeHandler) then OpcodeHandler
     281    if Assigned(OpcodeHandler) then OpcodeHandler
    229282    else raise Exception.Create('Opcode without handler: ' + IntToHex(Integer(Opcode), 2));
    230283  end else raise Exception.Create('Unknown opcode: ' + IntToHex(Integer(Opcode), 2));
     284  if (DataSize <> BaseDataSize) and (Opcode <> opSetSize) and (Opcode <> opSetSize8) and
     285    (Opcode <> opSetSize16) and (Opcode <> opSetSize32) and (Opcode <> opSetSize64) then
     286    DataSize := BaseDataSize;
    231287end;
    232288
     
    253309  Dest := ReadNext8;
    254310  Source := ReadNext8;
    255   PByte(@Registers[Dest])^ := PByte(@Registers[Source])^;
     311  PUInt8(@Registers[Dest])^ := PUInt8(@Registers[Source])^;
    256312end;
    257313
     
    263319  Dest := ReadNext8;
    264320  Source := ReadNext8;
    265   PWord(@Registers[Dest])^ := PWord(@Registers[Source])^;
     321  PUInt16(@Registers[Dest])^ := PUInt16(@Registers[Source])^;
    266322end;
    267323
     
    273329  Dest := ReadNext8;
    274330  Source := ReadNext8;
    275   PCardinal(@Registers[Dest])^ := PCardinal(@Registers[Source])^;
     331  PUInt32(@Registers[Dest])^ := PUInt32(@Registers[Source])^;
    276332end;
    277333
     
    283339  Dest := ReadNext8;
    284340  Source := ReadNext8;
    285   PQWord(@Registers[Dest])^ := PQWord(@Registers[Source])^;
     341  PUInt64(@Registers[Dest])^ := PUInt64(@Registers[Source])^;
    286342end;
    287343
     
    328384procedure TMachine.OpcodeCopyConst8;
    329385var
    330   Source: Byte;
    331   Dest: TRegIndex;
    332 begin
    333   Dest := ReadNext8;
    334   Source := ReadNext8;
    335   PByte(@Registers[Dest])^ := Source;
     386  Source: UInt8;
     387  Dest: TRegIndex;
     388begin
     389  Dest := ReadNext8;
     390  Source := ReadNext8;
     391  PUInt8(@Registers[Dest])^ := Source;
    336392end;
    337393
    338394procedure TMachine.OpcodeCopyConst16;
    339395var
    340   Source: Word;
     396  Source: UInt16;
    341397  Dest: TRegIndex;
    342398begin
    343399  Dest := ReadNext8;
    344400  Source := ReadNext16;
    345   PWord(@Registers[Dest])^ := Source;
     401  PUInt16(@Registers[Dest])^ := Source;
    346402end;
    347403
    348404procedure TMachine.OpcodeCopyConst32;
    349405var
    350   Source: Cardinal;
     406  Source: UInt32;
    351407  Dest: TRegIndex;
    352408begin
    353409  Dest := ReadNext8;
    354410  Source := ReadNext32;
    355   PCardinal(@Registers[Dest])^ := Source;
     411  PUInt32(@Registers[Dest])^ := Source;
    356412end;
    357413
    358414procedure TMachine.OpcodeCopyConst64;
    359415var
    360   Source: QWord;
     416  Source: UInt64;
    361417  Dest: TRegIndex;
    362418begin
    363419  Dest := ReadNext8;
    364420  Source := ReadNext64;
    365   PQWord(@Registers[Dest])^ := Source;
     421  PUInt64(@Registers[Dest])^ := Source;
    366422end;
    367423
     
    453509  Dec(SP, SizeOf(TDataInt));
    454510  PDataInt(@Memory[SP])^ := PDataInt(@Registers[Source])^;
     511end;
     512
     513procedure TMachine.OpcodePush8;
     514var
     515  Source: TRegIndex;
     516begin
     517  Source := ReadNext8;
     518  Dec(SP, SizeOf(Byte));
     519  PUInt8(@Memory[SP])^ := PUInt8(@Registers[Source])^;
     520end;
     521
     522procedure TMachine.OpcodePush16;
     523var
     524  Source: TRegIndex;
     525begin
     526  Source := ReadNext8;
     527  Dec(SP, SizeOf(Word));
     528  PUInt16(@Memory[SP])^ := PUInt16(@Registers[Source])^;
     529end;
     530
     531procedure TMachine.OpcodePush32;
     532var
     533  Source: TRegIndex;
     534begin
     535  Source := ReadNext8;
     536  Dec(SP, SizeOf(Cardinal));
     537  PUInt32(@Memory[SP])^ := PUInt32(@Registers[Source])^;
     538end;
     539
     540procedure TMachine.OpcodePush64;
     541var
     542  Source: TRegIndex;
     543begin
     544  Source := ReadNext8;
     545  Dec(SP, SizeOf(QWord));
     546  PUInt64(@Memory[SP])^ := PUInt64(@Registers[Source])^;
    455547end;
    456548
     
    485577begin
    486578  Reg := ReadNext8;
    487   PByte(@Registers[Reg])^ := PByte(@Registers[Reg])^ + 1;
     579  PUInt8(@Registers[Reg])^ := PUInt8(@Registers[Reg])^ + 1;
    488580end;
    489581
     
    493585begin
    494586  Reg := ReadNext8;
    495   PWord(@Registers[Reg])^ := PWord(@Registers[Reg])^ + 1;
     587  PUInt16(@Registers[Reg])^ := PUInt16(@Registers[Reg])^ + 1;
    496588end;
    497589
     
    501593begin
    502594  Reg := ReadNext8;
    503   PCardinal(@Registers[Reg])^ := PCardinal(@Registers[Reg])^ + 1;
     595  PUInt32(@Registers[Reg])^ := PUInt32(@Registers[Reg])^ + 1;
    504596end;
    505597
     
    509601begin
    510602  Reg := ReadNext8;
    511   PQWord(@Registers[Reg])^ := PQWord(@Registers[Reg])^ + 1;
     603  PUInt64(@Registers[Reg])^ := PUInt64(@Registers[Reg])^ + 1;
    512604end;
    513605
     
    520612end;
    521613
    522 procedure TMachine.OpcodeSkipNotZero;
     614procedure TMachine.OpcodeTestNotZero;
    523615var
    524616  Reg: TRegIndex;
    525617begin
    526618  Reg := ReadNext8;
    527   SkipNext := Registers[Reg] <> 0;
    528 end;
    529 
    530 procedure TMachine.OpcodeSkipZero;
     619  Condition := Registers[Reg] <> 0;
     620end;
     621
     622procedure TMachine.OpcodeTestZero;
    531623var
    532624  Reg: TRegIndex;
    533625begin
    534626  Reg := ReadNext8;
    535   SkipNext := Registers[Reg] = 0;
     627  Condition := Registers[Reg] = 0;
    536628end;
    537629
     
    540632  RelAddr: TAddrInt;
    541633begin
    542   OpcodeSkipNotZero;
     634  RelAddr := ReadNextS;
     635  IP := IP + RelAddr;
     636end;
     637
     638procedure TMachine.OpcodeJumpAbs;
     639var
     640  Addr: TAddrInt;
     641begin
     642  Addr := ReadNext;
     643  IP := Addr;
     644end;
     645
     646procedure TMachine.OpcodeJumpRelCond;
     647var
     648  RelAddr: TAddrInt;
     649begin
     650  RelAddr := ReadNextS;
     651  if Condition then IP := IP + RelAddr;
     652end;
     653
     654procedure TMachine.OpcodeJumpRelCond8;
     655var
     656  RelAddr: Int8;
     657begin
    543658  RelAddr := ReadNextS8;
    544   if not SkipNext then IP := IP + RelAddr;
    545 end;
    546 
    547 procedure TMachine.OpcodeJumpAbs;
     659  if Condition then IP := IP + RelAddr;
     660end;
     661
     662procedure TMachine.OpcodeJumpAbsCond;
    548663var
    549664  Addr: TAddrInt;
    550665begin
    551   OpcodeSkipNotZero;
    552666  Addr := ReadNext;
    553   if not SkipNext then IP := Addr;
     667  if Condition then IP := Addr;
     668end;
     669
     670procedure TMachine.OpcodeCallRel;
     671var
     672  RelAddr: TAddrInt;
     673begin
     674  RelAddr := ReadNextS;
     675  Dec(SP, SizeOf(TAddrInt));
     676  PAddrInt(@Memory[SP])^ := IP;
     677  IP := IP + RelAddr;
     678end;
     679
     680procedure TMachine.OpcodeCallAbs;
     681var
     682  Addr: TAddrInt;
     683begin
     684  Addr := ReadNext;
     685  Dec(SP, SizeOf(TAddrInt));
     686  PAddrInt(@Memory[SP])^ := IP;
     687  IP := Addr;
     688end;
     689
     690procedure TMachine.OpcodeCallRelCond;
     691var
     692  RelAddr: TAddrInt;
     693begin
     694  RelAddr := ReadNextS;
     695  if Condition then begin
     696    Dec(SP, SizeOf(TAddrInt));
     697    PAddrInt(@Memory[SP])^ := IP;
     698    IP := IP + RelAddr;
     699  end;
     700end;
     701
     702procedure TMachine.OpcodeCallAbsCond;
     703var
     704  Addr: TAddrInt;
     705begin
     706  Dec(SP, SizeOf(TAddrInt));
     707  if Condition then begin
     708    PAddrInt(@Memory[SP])^ := IP;
     709    Addr := ReadNext;
     710    IP := Addr;
     711  end;
    554712end;
    555713
     
    557715begin
    558716  raise Exception.Create('Unsupported instruction');
     717end;
     718
     719procedure TMachine.OpcodeSetSize;
     720begin
     721  DataSize := dsNative;
     722end;
     723
     724procedure TMachine.OpcodeSetSize8;
     725begin
     726  DataSize := ds8;
     727end;
     728
     729procedure TMachine.OpcodeSetSize16;
     730begin
     731  DataSize := ds16;
     732end;
     733
     734procedure TMachine.OpcodeSetSize32;
     735begin
     736  DataSize := ds32;
     737end;
     738
     739procedure TMachine.OpcodeSetSize64;
     740begin
     741  DataSize := ds64;
    559742end;
    560743
     
    572755end;
    573756
     757function TMachine.ReadNextS: TDataInt;
     758begin
     759  CheckIP;
     760  Result := PDataInt(@Memory[IP])^;
     761  Inc(IP, SizeOf(TDataInt));
     762end;
     763
    574764function TMachine.ReadNext8: Byte;
    575765begin
     
    615805end;
    616806
     807procedure TInstructionWriter.AddDataS(Data: Int64);
     808begin
     809  PInt64(@(Machine.Memory[Addr]))^ := Data;
     810  Inc(Addr, SizeOf(Int64));
     811end;
     812
    617813procedure TInstructionWriter.AddData8(Data: Byte);
    618814begin
     
    634830end;
    635831
     832procedure TInstructionWriter.AddCopyConst8(Reg: TRegIndex; Value: UInt8);
     833begin
     834  AddData8(Integer(opSetSize8));
     835  AddData8(Integer(opCopyConst));
     836  AddData8(Reg);
     837  AddData8(Value);
     838end;
     839
    636840procedure TInstructionWriter.AddGetDataSize(Reg: TRegIndex);
    637841begin
     
    671875end;
    672876
    673 procedure TInstructionWriter.AddJumpRelNotZero(Reg: TRegIndex; RelAddr: Integer
    674   );
    675 begin
    676   AddData8(Integer(opJumpRel));
     877procedure TInstructionWriter.AddTestNotZero(Reg: TRegIndex);
     878begin
     879  AddData8(Integer(opTestNotZero));
    677880  AddData8(Reg);
    678   AddDataS8(RelAddr - 3);
     881end;
     882
     883procedure TInstructionWriter.AddJumpRelCond(RelAddr: Integer);
     884begin
     885  AddData8(Integer(opJumpRelCond));
     886  AddDataS(RelAddr - SizeOf(Byte) - SizeOf(TDataInt));
     887end;
     888
     889procedure TInstructionWriter.AddJumpRelCond8(RelAddr: ShortInt);
     890begin
     891  AddData8(Integer(opSetSize8));
     892  AddData8(Integer(opJumpRelCond));
     893  AddDataS8(RelAddr - SizeOf(Byte) - SizeOf(TDataInt));
    679894end;
    680895
Note: See TracChangeset for help on using the changeset viewer.