Changeset 159


Ignore:
Timestamp:
Apr 25, 2018, 11:31:04 AM (7 years ago)
Author:
chronos
Message:
  • Added: Instruction writer class.
  • Added: Support for lower data width memory operations.
Location:
branches/virtualcpu3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu3/UFormMain.pas

    r155 r159  
    3636  TCPU32 = specialize TCPU<Integer>;
    3737  TCPU64 = specialize TCPU<Int64>;
     38  //TCPU128 = specialize TCPU<Int128>;
     39  TInstWriter8 = specialize TInstructionWriter<ShortInt>;
     40  TInstWriter16 = specialize TInstructionWriter<SmallInt>;
     41  TInstWriter32 = specialize TInstructionWriter<Integer>;
     42  TInstWriter64 = specialize TInstructionWriter<Int64>;
     43  //TInstWriter128 = specialize TInstructionWriter<Int128>;
    3844var
    3945  CPU8: TCPU8;
     
    4147  CPU32: TCPU32;
    4248  CPU64: TCPU64;
     49  Writer8: TInstWriter8;
     50  Writer16: TInstWriter16;
     51  Writer32: TInstWriter32;
     52  Writer64: TInstWriter64;
    4353begin
    4454  CPU8 := TCPU8.Create;
     55  Writer8 := TInstWriter8.Create;
     56  Writer8.Machine := CPU8;
     57  Writer8.AddLoadConst(0, 1);
     58  Writer8.AddHalt;
     59  Writer8.Free;
    4560  CPU8.Run;
    4661  CPU8.Free;
    4762
    4863  CPU16 := TCPU16.Create;
     64  Writer16 := TInstWriter16.Create;
     65  Writer16.Machine := CPU16;
     66  Writer16.AddLoadConst(0, 1);
     67  Writer16.AddHalt;
     68  Writer16.Free;
    4969  CPU16.Run;
    5070  CPU16.Free;
    5171
    5272  CPU32 := TCPU32.Create;
     73  Writer32 := TInstWriter32.Create;
     74  Writer32.Machine := CPU32;
     75  Writer32.AddLoadConst(0, 1);
     76  Writer32.AddHalt;
     77  Writer32.Free;
    5378  CPU32.Run;
    5479  CPU32.Free;
    5580
    5681  CPU64 := TCPU64.Create;
     82  Writer64 := TInstWriter64.Create;
     83  Writer64.Machine := CPU64;
     84  Writer64.AddLoadConst(0, 1);
     85  Writer64.AddHalt;
     86  Writer64.Free;
    5787  CPU64.Run;
    5888  CPU64.Free;
  • branches/virtualcpu3/UMachine.pas

    r158 r159  
    1212{$DEFINE EXT_GENERAL}
    1313{$DEFINE EXT_BIT}
     14//{$DEFINE EXT_LOWER_WIDTH}
    1415
    1516// Extension dependencies
     
    3031    opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc,
    3132    opTstZ, opTstNZ, opTstC, opTstNC, opLDMD, opSTMD, opLdir, opLddr,
    32     opBitSet, opBitRes, opBitGet, opBitPut);
     33    opBitSet, opBitRes, opBitGet, opBitPut,
     34    opPrefix8, opPrefix16, opPrefix32, opPrefix64);
    3335
    3436  TOpcodeHandler = procedure of object;
     37
     38  TDataWidth = (dwNative, dw8, dw16, dw32, dw64, dw128);
    3539
    3640  // Goals: Simple to implement, fast execution
     
    5458    OpcodeHandlers: array[TOpcode] of TOpcodeHandler;
    5559    function ReadNext: T;
     60    {$IFDEF EXT_LOWER_WIDTH}
     61    function ReadNext8: ShortInt;
     62    function ReadNext16: SmallInt;
     63    function ReadNext32: Integer;
     64    function ReadNext64: Int64;
     65    {$ENDIF}
    5666    function ReadOpcode: TOpcodeIndex;
    5767    function ReadReg: TRegIndex;
     
    7989    procedure OpcodeTestNotCarry;
    8090    procedure OpcodeTestCarry;
     91    {$IFDEF EXT_LOWER_WIDTH}
     92    procedure OpcodePrefix8;
     93    procedure OpcodePrefix16;
     94    procedure OpcodePrefix32;
     95    procedure OpcodePrefix64;
     96    {$ENDIF}
    8197    {$IFDEF EXT_GENERAL}
    8298    procedure OpcodeExchange;
     
    127143    Memory: array of Byte;
    128144    IP: T;
     145    DataWidth: TDataWidth;
    129146    {$IFDEF EXT_STACK}
    130147    SP: T;
     
    136153  end;
    137154
     155  { TInstructionWriter }
     156
     157  generic TInstructionWriter<T> = class
     158  type
     159    PT = ^T;
     160    TOpcodeIndex = Byte;
     161    POpcodeIndex = ^TOpcodeIndex;
     162    TRegIndex = Byte;
     163    PRegIndex = ^TRegIndex;
     164  var
     165    Addr: Integer;
     166    Machine: specialize TCPU<T>;
     167    procedure AddLoadConst(Reg: TRegIndex; Value: T);
     168    {$IFDEF EXT_LOWER_WIDTH}
     169    procedure AddLoadConst8(Reg: TRegIndex; Value: ShortInt);
     170    procedure AddLoadConst16(Reg: TRegIndex; Value: SmallInt);
     171    procedure AddLoadConst32(Reg: TRegIndex; Value: Integer);
     172    procedure AddLoadConst64(Reg: TRegIndex; Value: Int64);
     173    {$ENDIF}
     174    procedure AddNop;
     175    procedure AddHalt;
     176    procedure AddReg(Reg: TRegIndex);
     177    procedure AddOpcode(Opcode: TOpcode);
     178    procedure AddData(Value: T);
     179    {$IFDEF EXT_LOWER_WIDTH}
     180    procedure AddData8(Value: ShortInt);
     181    procedure AddData16(Value: SmallInt);
     182    procedure AddData32(Value: Integer);
     183    procedure AddData64(Value: Int64);
     184    {$ENDIF}
     185  end;
     186
    138187
    139188implementation
     189
     190{ TInstructionWriter }
     191
     192procedure TInstructionWriter.AddLoadConst(Reg: TRegIndex; Value: T);
     193begin
     194  AddOpcode(opLDC);
     195  AddReg(Reg);
     196  AddData(Value);
     197end;
     198
     199{$IFDEF EXT_LOWER_WIDTH}
     200procedure TInstructionWriter.AddLoadConst8(Reg: TRegIndex; Value: ShortInt);
     201begin
     202  AddOpcode(opPrefix8);
     203  AddOpcode(opLDC);
     204  AddData8(Reg);
     205  AddData8(Value);
     206end;
     207
     208procedure TInstructionWriter.AddLoadConst16(Reg: TRegIndex; Value: SmallInt);
     209begin
     210  AddOpcode(opPrefix16);
     211  AddOpcode(opLDC);
     212  AddReg(Reg);
     213  AddData16(Value);
     214end;
     215
     216procedure TInstructionWriter.AddLoadConst32(Reg: TRegIndex; Value: Integer);
     217begin
     218  AddOpcode(opPrefix32);
     219  AddOpcode(opLDC);
     220  AddReg(Reg);
     221  AddData32(Value);
     222end;
     223
     224procedure TInstructionWriter.AddLoadConst64(Reg: TRegIndex; Value: Int64);
     225begin
     226  AddOpcode(opPrefix64);
     227  AddOpcode(opLDC);
     228  AddReg(Reg);
     229  AddData64(Value);
     230end;
     231{$ENDIF}
     232
     233procedure TInstructionWriter.AddNop;
     234begin
     235  AddOpcode(opNop);
     236end;
     237
     238procedure TInstructionWriter.AddHalt;
     239begin
     240  AddOpcode(opHalt);
     241end;
     242
     243procedure TInstructionWriter.AddReg(Reg: TRegIndex);
     244begin
     245  PRegIndex(@(Machine.Memory[Addr]))^ := Reg;
     246  Inc(Addr, SizeOf(TRegIndex));
     247end;
     248
     249procedure TInstructionWriter.AddOpcode(Opcode: TOpcode);
     250begin
     251  POpcodeIndex(@(Machine.Memory[Addr]))^ := TOpcodeIndex(Opcode);
     252  Inc(Addr, SizeOf(TOpcodeIndex));
     253end;
     254
     255procedure TInstructionWriter.AddData(Value: T);
     256begin
     257  PT(@(Machine.Memory[Addr]))^ := Value;
     258  Inc(Addr, SizeOf(T));
     259end;
     260
     261{$IFDEF EXT_LOWER_WIDTH}
     262procedure TInstructionWriter.AddData8(Value: ShortInt);
     263begin
     264  PShortInt(@(Machine.Memory[Addr]))^ := Value;
     265  Inc(Addr, SizeOf(ShortInt));
     266end;
     267
     268procedure TInstructionWriter.AddData16(Value: SmallInt);
     269begin
     270  PSmallInt(@(Machine.Memory[Addr]))^ := Value;
     271  Inc(Addr, SizeOf(SmallInt));
     272end;
     273
     274procedure TInstructionWriter.AddData32(Value: Integer);
     275begin
     276  PInteger(@(Machine.Memory[Addr]))^ := Value;
     277  Inc(Addr, SizeOf(Integer));
     278end;
     279
     280procedure TInstructionWriter.AddData64(Value: Int64);
     281begin
     282  PInt64(@(Machine.Memory[Addr]))^ := Value;
     283  Inc(Addr, SizeOf(Int64));
     284end;
     285{$ENDIF}
    140286
    141287{ TCPU }
     
    146292  Inc(IP, SizeOf(T));
    147293end;
     294
     295{$IFDEF EXT_LOWER_WIDTH}
     296function TCPU.ReadNext8: ShortInt;
     297begin
     298  Result := PShortInt(@Memory[IP])^;
     299  Inc(IP, SizeOf(ShortInt));
     300end;
     301
     302function TCPU.ReadNext16: SmallInt;
     303begin
     304  Result := PSmallInt(@Memory[IP])^;
     305  Inc(IP, SizeOf(SmallInt));
     306end;
     307
     308function TCPU.ReadNext32: Integer;
     309begin
     310  Result := PInteger(@Memory[IP])^;
     311  Inc(IP, SizeOf(Integer));
     312end;
     313
     314function TCPU.ReadNext64: Int64;
     315begin
     316  Result := PInt64(@Memory[IP])^;
     317  Inc(IP, SizeOf(Int64));
     318end;
     319{$ENDIF}
    148320
    149321function TCPU.ReadOpcode: TOpcodeIndex;
     
    165337  SP := Length(Memory);
    166338  {$ENDIF}
     339  {$IFDEF EXT_LOWER_WIDTH}
     340  DataWidth := dwNative;
     341  {$ENDIF}
    167342  Terminated := False;
    168343  while not Terminated do
     
    200375begin
    201376  Reg := ReadReg;
     377  {$IFDEF EXT_LOWER_WIDTH}
     378  case DataWidth of
     379    dwNative: Registers[Reg] := ReadNext;
     380    dw8: Registers[Reg] := ReadNext8;
     381    dw16: Registers[Reg] := ReadNext16;
     382    dw32: Registers[Reg] := ReadNext32;
     383    dw64: Registers[Reg] := ReadNext64;
     384  end;
     385  {$ELSE}
    202386  Registers[Reg] := ReadNext;
     387  {$ENDIF}
    203388end;
    204389
     
    209394  Dest := ReadReg;
    210395  Src := ReadReg;
     396  {$IFDEF EXT_LOWER_WIDTH}
     397  case DataWidth of
     398    dwNative: Registers[Dest] := PT(@Memory[Registers[Src]])^;
     399    dw8: Registers[Dest] := PShortInt(@Memory[Registers[Src]])^;
     400    dw16: Registers[Dest] := PSmallInt(@Memory[Registers[Src]])^;
     401    dw32: Registers[Dest] := PInteger(@Memory[Registers[Src]])^;
     402    dw64: Registers[Dest] := PInt64(@Memory[Registers[Src]])^;
     403  end;
     404  {$ELSE}
    211405  Registers[Dest] := PT(@Memory[Registers[Src]])^;
     406  {$ENDIF}
    212407end;
    213408
     
    218413  Dest := ReadReg;
    219414  Src := ReadReg;
     415  {$IFDEF EXT_LOWER_WIDTH}
     416  case DataWidth of
     417    dwNative: PT(@Memory[Registers[Dest]])^ := Registers[Src];
     418    dw8: PShortInt(@Memory[Registers[Dest]])^ := Registers[Src];
     419    dw16: PSmallInt(@Memory[Registers[Dest]])^ := Registers[Src];
     420    dw32: PInteger(@Memory[Registers[Dest]])^ := Registers[Src];
     421    dw64: PInt64(@Memory[Registers[Dest]])^ := Registers[Src];
     422  end;
     423  {$ELSE}
    220424  PT(@Memory[Registers[Dest]])^ := Registers[Src];
     425  {$ENDIF}
    221426end;
    222427
     
    467672  Condition := Registers[Reg2] > Registers[Reg1];
    468673end;
     674
     675{$IFDEF EXT_LOWER_WIDTH}
     676procedure TCPU.OpcodePrefix8;
     677begin
     678  DataWidth := dw8;
     679end;
     680
     681procedure TCPU.OpcodePrefix16;
     682begin
     683  DataWidth := dw16;
     684end;
     685
     686procedure TCPU.OpcodePrefix32;
     687begin
     688  DataWidth := dw32;
     689end;
     690
     691procedure TCPU.OpcodePrefix64;
     692begin
     693  DataWidth := dw64;
     694end;
     695{$ENDIF}
    469696
    470697procedure TCPU.OpcodeTestNotZero;
     
    520747  end;
    521748end;
     749{$ENDIF}
    522750
    523751{$IFDEF EXT_BIT}
     
    562790    Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]);
    563791end;
    564 {$ENDIF}
    565 
    566792{$ENDIF}
    567793
     
    577803    else raise Exception.Create('Missing handler for opcode + ' + IntToStr(Integer(Opcode)));
    578804  end else raise Exception.Create('Unknown opcode: ' + IntToStr(Integer(Opcode)));
     805  {$IFDEF EXT_LOWER_WIDTH}
     806  if (Opcode <> opPrefix8) and (Opcode <> opPrefix16) and (Opcode <> opPrefix32) and
     807  (Opcode <> opPrefix64) then
     808    DataWidth := dwNative;
     809  {$ENDIF}
    579810end;
    580811
Note: See TracChangeset for help on using the changeset viewer.