Ignore:
Timestamp:
Apr 12, 2019, 2:03:51 PM (5 years ago)
Author:
chronos
Message:
  • Modified: Better use data and address prefix opcodes.
  • Added: More instructions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu4/UInstructionWriter.pas

    r174 r177  
    1313
    1414  TInstructionWriter = class
     15  private
     16    DataSizeLast: TBitWidth;
     17    DataSizePrefix: TBitWidth;
     18    AddrSizeLast: TBitWidth;
     19    AddrSizePrefix: TBitWidth;
     20    procedure PrefixBegin;
     21    procedure PrefixEnd;
     22  public
    1523    Cpu: TCpu;
    1624    IP: Integer;
     25    DataSize: TBitWidth;
     26    AddrSize: TBitWidth;
     27    procedure Init;
    1728    procedure Write8(Value: Byte);
    1829    procedure Write16(Value: Word);
     
    2031    procedure Write64(Value: QWord);
    2132    procedure WriteAddress(Value: TAddress);
     33    procedure WriteAddressSigned(Value: TAddressSigned);
    2234    procedure WriteData(Value: QWord);
    2335    procedure WriteString(Text: string);
     
    2739    procedure Increment(Reg: TRegIndex);
    2840    procedure Decrement(Reg: TRegIndex);
    29     procedure Jump(Value: QWord);
    30     procedure JumpNotZero(Value: QWord);
     41    procedure Jump(Addr: QWord);
     42    procedure JumpNotZero(Addr: QWord);
     43    procedure JumpZero(Addr: QWord);
     44    procedure JumpRel(Addr: QWord);
     45    procedure JumpRelNotZero(Addr: QWord);
     46    procedure JumpRelZero(Addr: QWord);
    3147    procedure DataPrefix8;
    3248    procedure DataPrefix16;
    3349    procedure DataPrefix32;
    3450    procedure DataPrefix64;
     51    procedure AddrPrefix8;
     52    procedure AddrPrefix16;
     53    procedure AddrPrefix32;
     54    procedure AddrPrefix64;
    3555    procedure StoreMem(RegAddr, RegSrc: TRegIndex);
    3656    procedure LoadMem(RegDst, RegAddr: TRegIndex);
     
    4060  end;
    4161
     62  { TAssembler }
     63
     64  TAssembler = class
     65    Source: TStringList;
     66    Dest: array of Byte;
     67    procedure Compile;
     68  end;
     69
     70  TDisassembler = class
     71
     72  end;
     73
     74const
     75  OpcodeName: array[TOpcode] of string = ('NOP', 'HALT', 'LD', 'LDI', 'JP', 'JPZ',
     76    'JPNZ', 'JR', 'JRZ', 'JRNZ', 'NEG', 'CLR', 'LDM', 'STM', 'EX', 'PUSH', 'POP',
     77    'CALL', 'RET', 'ADD', 'ADDI', 'SUB', 'SUBI', 'INC', 'DEC', 'IN', 'OUT',
     78    'SHL', 'SHR', 'DP8', 'DP16', 'DP32', 'DP64', 'DS', 'AS', 'TEST', 'AND', 'OR',
     79    'XOR', 'LDDR', 'LDIR', 'MUL', 'DIV', 'MOD', 'AP8', 'AP16', 'AP32', 'AP64');
    4280
    4381implementation
    4482
     83{ TAssembler }
     84
     85procedure TAssembler.Compile;
     86begin
     87
     88end;
     89
    4590{ TInstructionWriter }
    4691
    4792procedure TInstructionWriter.Nop;
    4893begin
     94  PrefixBegin;
    4995  Write8(Byte(opNop));
     96  PrefixEnd;
    5097end;
    5198
    5299procedure TInstructionWriter.Halt;
    53100begin
     101  PrefixBegin;
    54102  Write8(Byte(opHalt));
     103  PrefixEnd;
    55104end;
    56105
    57106procedure TInstructionWriter.Loadi(Reg: TRegIndex; Value: QWord);
    58107begin
     108  PrefixBegin;
    59109  Write8(Byte(opLoadi));
    60110  Write8(Reg);
    61111  WriteData(Value);
     112  PrefixEnd;
    62113end;
    63114
    64115procedure TInstructionWriter.Increment(Reg: TRegIndex);
    65116begin
     117  PrefixBegin;
    66118  Write8(Byte(opInc));
    67119  Write8(Reg);
     120  PrefixEnd;
    68121end;
    69122
    70123procedure TInstructionWriter.Decrement(Reg: TRegIndex);
    71124begin
     125  PrefixBegin;
    72126  Write8(Byte(opDec));
    73127  Write8(Reg);
    74 end;
    75 
    76 procedure TInstructionWriter.Jump(Value: QWord);
    77 begin
     128  PrefixEnd;
     129end;
     130
     131procedure TInstructionWriter.Jump(Addr: QWord);
     132begin
     133  PrefixBegin;
    78134  Write8(Byte(opJump));
    79   WriteAddress(Value);
    80 end;
    81 
    82 procedure TInstructionWriter.JumpNotZero(Value: QWord);
    83 begin
     135  WriteAddress(Addr);
     136  PrefixEnd;
     137end;
     138
     139procedure TInstructionWriter.JumpNotZero(Addr: QWord);
     140begin
     141  PrefixBegin;
    84142  Write8(Byte(opJumpNotZero));
    85   WriteAddress(Value);
     143  WriteAddress(Addr);
     144  PrefixEnd;
     145end;
     146
     147procedure TInstructionWriter.JumpZero(Addr: QWord);
     148begin
     149  PrefixBegin;
     150  Write8(Byte(opJumpZero));
     151  WriteAddress(Addr);
     152  PrefixEnd;
     153end;
     154
     155procedure TInstructionWriter.JumpRel(Addr: QWord);
     156var
     157  NextIP: QWord;
     158begin
     159  PrefixBegin;
     160  NextIP := IP + 1 + BitWidthBytes[Cpu.AddrSize];
     161  Write8(Byte(opJumpRel));
     162  WriteAddressSigned(Int64(Addr) - Int64(NextIP));
     163  PrefixEnd;
     164end;
     165
     166procedure TInstructionWriter.JumpRelNotZero(Addr: QWord);
     167var
     168  NextIP: QWord;
     169begin
     170  PrefixBegin;
     171  NextIP := IP + 1 + BitWidthBytes[Cpu.AddrSize];
     172  Write8(Byte(opJumpRelNotZero));
     173  WriteAddressSigned(Int64(Addr) - Int64(NextIP));
     174  PrefixEnd;
     175end;
     176
     177procedure TInstructionWriter.JumpRelZero(Addr: QWord);
     178var
     179  NextIP: QWord;
     180begin
     181  PrefixBegin;
     182  NextIP := IP + 1 + BitWidthBytes[Cpu.AddrSize];
     183  Write8(Byte(opJumpRelZero));
     184  WriteAddressSigned(Int64(Addr) - Int64(NextIP));
     185  if AddrSizeLast <> bwNone then AddrSize := AddrSizeLast;
     186  PrefixEnd;
    86187end;
    87188
    88189procedure TInstructionWriter.DataPrefix8;
    89190begin
     191  DataSizePrefix := bw8;
    90192  Write8(Byte(opDataPrefix8));
    91193end;
     
    93195procedure TInstructionWriter.DataPrefix16;
    94196begin
     197  DataSizePrefix := bw16;
    95198  Write8(Byte(opDataPrefix16));
    96199end;
     
    98201procedure TInstructionWriter.DataPrefix32;
    99202begin
     203  DataSizePrefix := bw32;
    100204  Write8(Byte(opDataPrefix32));
    101205end;
     
    103207procedure TInstructionWriter.DataPrefix64;
    104208begin
     209  DataSizePrefix := bw64;
    105210  Write8(Byte(opDataPrefix64));
     211end;
     212
     213procedure TInstructionWriter.AddrPrefix8;
     214begin
     215  AddrSizePrefix := bw8;
     216  Write8(Byte(opAddrPrefix8));
     217end;
     218
     219procedure TInstructionWriter.AddrPrefix16;
     220begin
     221  AddrSizePrefix := bw16;
     222  Write8(Byte(opAddrPrefix16));
     223end;
     224
     225procedure TInstructionWriter.AddrPrefix32;
     226begin
     227  AddrSizePrefix := bw32;
     228  Write8(Byte(opAddrPrefix32));
     229end;
     230
     231procedure TInstructionWriter.AddrPrefix64;
     232begin
     233  AddrSizePrefix := bw64;
     234  Write8(Byte(opAddrPrefix64));
    106235end;
    107236
     
    115244procedure TInstructionWriter.LoadMem(RegDst, RegAddr: TRegIndex);
    116245begin
     246  PrefixBegin;
    117247  Write8(Byte(opLoadMem));
    118248  Write8(RegDst);
    119249  Write8(RegAddr);
     250  PrefixEnd;
    120251end;
    121252
    122253procedure TInstructionWriter.Output(Port: TAddress; Reg: TRegIndex);
    123254begin
     255  PrefixBegin;
    124256  Write8(Byte(opOut));
    125257  WriteAddress(Port);
    126258  Write8(Reg);
     259  PrefixEnd;
    127260end;
    128261
    129262procedure TInstructionWriter.Input(Reg: TRegIndex; Port: TAddress);
    130263begin
     264  PrefixBegin;
    131265  Write8(Byte(opIn));
    132266  Write8(Reg);
    133267  WriteAddress(Port);
     268  PrefixEnd;
    134269end;
    135270
    136271procedure TInstructionWriter.Test(Reg: TRegIndex);
    137272begin
     273  PrefixBegin;
    138274  Write8(Byte(opTest));
    139275  Write8(Reg);
     276  Prefixend;
    140277end;
    141278
     
    148285end;
    149286
     287procedure TInstructionWriter.PrefixBegin;
     288begin
     289  if DataSizePrefix <> bwNone then begin
     290    DataSizeLast := DataSize;
     291    DataSize := DataSizePrefix;
     292    DataSizePrefix := bwNone;
     293  end;
     294  if AddrSizePrefix <> bwNone then begin
     295    AddrSizeLast := AddrSize;
     296    AddrSize := AddrSizePrefix;
     297    AddrSizePrefix := bwNone;
     298  end;
     299end;
     300
     301procedure TInstructionWriter.PrefixEnd;
     302begin
     303  if DataSizeLast <> bwNone then begin
     304    DataSize := DataSizeLast;
     305    DataSizeLast := bwNone;
     306  end;
     307  if AddrSizeLast <> bwNone then begin
     308    AddrSize := AddrSizeLast;
     309    AddrSizeLast := bwNone;
     310  end;
     311end;
     312
     313procedure TInstructionWriter.Init;
     314begin
     315  DataSize := Cpu.DataSize;
     316  AddrSize := Cpu.AddrSize;
     317end;
     318
    150319procedure TInstructionWriter.Write8(Value: Byte);
    151320begin
     
    174343procedure TInstructionWriter.WriteAddress(Value: TAddress);
    175344begin
    176   case Cpu.AddressSize of
     345  case AddrSize of
    177346    bw8: Write8(Value);
    178347    bw16: Write16(Value);
     
    182351end;
    183352
     353procedure TInstructionWriter.WriteAddressSigned(Value: TAddressSigned);
     354begin
     355  case AddrSize of
     356    bw8: Write8(Byte(Value));
     357    bw16: Write16(Word(Value));
     358    bw32: Write32(DWord(Value));
     359    bw64: Write64(QWord(Value));
     360  end;
     361end;
     362
    184363procedure TInstructionWriter.WriteData(Value: QWord);
    185364begin
    186   case Cpu.DataSize of
     365  case DataSize of
    187366    bw8: Write8(Value);
    188367    bw16: Write16(Value);
Note: See TracChangeset for help on using the changeset viewer.