Changeset 159
- Timestamp:
- Apr 25, 2018, 11:31:04 AM (7 years ago)
- Location:
- branches/virtualcpu3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu3/UFormMain.pas
r155 r159 36 36 TCPU32 = specialize TCPU<Integer>; 37 37 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>; 38 44 var 39 45 CPU8: TCPU8; … … 41 47 CPU32: TCPU32; 42 48 CPU64: TCPU64; 49 Writer8: TInstWriter8; 50 Writer16: TInstWriter16; 51 Writer32: TInstWriter32; 52 Writer64: TInstWriter64; 43 53 begin 44 54 CPU8 := TCPU8.Create; 55 Writer8 := TInstWriter8.Create; 56 Writer8.Machine := CPU8; 57 Writer8.AddLoadConst(0, 1); 58 Writer8.AddHalt; 59 Writer8.Free; 45 60 CPU8.Run; 46 61 CPU8.Free; 47 62 48 63 CPU16 := TCPU16.Create; 64 Writer16 := TInstWriter16.Create; 65 Writer16.Machine := CPU16; 66 Writer16.AddLoadConst(0, 1); 67 Writer16.AddHalt; 68 Writer16.Free; 49 69 CPU16.Run; 50 70 CPU16.Free; 51 71 52 72 CPU32 := TCPU32.Create; 73 Writer32 := TInstWriter32.Create; 74 Writer32.Machine := CPU32; 75 Writer32.AddLoadConst(0, 1); 76 Writer32.AddHalt; 77 Writer32.Free; 53 78 CPU32.Run; 54 79 CPU32.Free; 55 80 56 81 CPU64 := TCPU64.Create; 82 Writer64 := TInstWriter64.Create; 83 Writer64.Machine := CPU64; 84 Writer64.AddLoadConst(0, 1); 85 Writer64.AddHalt; 86 Writer64.Free; 57 87 CPU64.Run; 58 88 CPU64.Free; -
branches/virtualcpu3/UMachine.pas
r158 r159 12 12 {$DEFINE EXT_GENERAL} 13 13 {$DEFINE EXT_BIT} 14 //{$DEFINE EXT_LOWER_WIDTH} 14 15 15 16 // Extension dependencies … … 30 31 opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, 31 32 opTstZ, opTstNZ, opTstC, opTstNC, opLDMD, opSTMD, opLdir, opLddr, 32 opBitSet, opBitRes, opBitGet, opBitPut); 33 opBitSet, opBitRes, opBitGet, opBitPut, 34 opPrefix8, opPrefix16, opPrefix32, opPrefix64); 33 35 34 36 TOpcodeHandler = procedure of object; 37 38 TDataWidth = (dwNative, dw8, dw16, dw32, dw64, dw128); 35 39 36 40 // Goals: Simple to implement, fast execution … … 54 58 OpcodeHandlers: array[TOpcode] of TOpcodeHandler; 55 59 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} 56 66 function ReadOpcode: TOpcodeIndex; 57 67 function ReadReg: TRegIndex; … … 79 89 procedure OpcodeTestNotCarry; 80 90 procedure OpcodeTestCarry; 91 {$IFDEF EXT_LOWER_WIDTH} 92 procedure OpcodePrefix8; 93 procedure OpcodePrefix16; 94 procedure OpcodePrefix32; 95 procedure OpcodePrefix64; 96 {$ENDIF} 81 97 {$IFDEF EXT_GENERAL} 82 98 procedure OpcodeExchange; … … 127 143 Memory: array of Byte; 128 144 IP: T; 145 DataWidth: TDataWidth; 129 146 {$IFDEF EXT_STACK} 130 147 SP: T; … … 136 153 end; 137 154 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 138 187 139 188 implementation 189 190 { TInstructionWriter } 191 192 procedure TInstructionWriter.AddLoadConst(Reg: TRegIndex; Value: T); 193 begin 194 AddOpcode(opLDC); 195 AddReg(Reg); 196 AddData(Value); 197 end; 198 199 {$IFDEF EXT_LOWER_WIDTH} 200 procedure TInstructionWriter.AddLoadConst8(Reg: TRegIndex; Value: ShortInt); 201 begin 202 AddOpcode(opPrefix8); 203 AddOpcode(opLDC); 204 AddData8(Reg); 205 AddData8(Value); 206 end; 207 208 procedure TInstructionWriter.AddLoadConst16(Reg: TRegIndex; Value: SmallInt); 209 begin 210 AddOpcode(opPrefix16); 211 AddOpcode(opLDC); 212 AddReg(Reg); 213 AddData16(Value); 214 end; 215 216 procedure TInstructionWriter.AddLoadConst32(Reg: TRegIndex; Value: Integer); 217 begin 218 AddOpcode(opPrefix32); 219 AddOpcode(opLDC); 220 AddReg(Reg); 221 AddData32(Value); 222 end; 223 224 procedure TInstructionWriter.AddLoadConst64(Reg: TRegIndex; Value: Int64); 225 begin 226 AddOpcode(opPrefix64); 227 AddOpcode(opLDC); 228 AddReg(Reg); 229 AddData64(Value); 230 end; 231 {$ENDIF} 232 233 procedure TInstructionWriter.AddNop; 234 begin 235 AddOpcode(opNop); 236 end; 237 238 procedure TInstructionWriter.AddHalt; 239 begin 240 AddOpcode(opHalt); 241 end; 242 243 procedure TInstructionWriter.AddReg(Reg: TRegIndex); 244 begin 245 PRegIndex(@(Machine.Memory[Addr]))^ := Reg; 246 Inc(Addr, SizeOf(TRegIndex)); 247 end; 248 249 procedure TInstructionWriter.AddOpcode(Opcode: TOpcode); 250 begin 251 POpcodeIndex(@(Machine.Memory[Addr]))^ := TOpcodeIndex(Opcode); 252 Inc(Addr, SizeOf(TOpcodeIndex)); 253 end; 254 255 procedure TInstructionWriter.AddData(Value: T); 256 begin 257 PT(@(Machine.Memory[Addr]))^ := Value; 258 Inc(Addr, SizeOf(T)); 259 end; 260 261 {$IFDEF EXT_LOWER_WIDTH} 262 procedure TInstructionWriter.AddData8(Value: ShortInt); 263 begin 264 PShortInt(@(Machine.Memory[Addr]))^ := Value; 265 Inc(Addr, SizeOf(ShortInt)); 266 end; 267 268 procedure TInstructionWriter.AddData16(Value: SmallInt); 269 begin 270 PSmallInt(@(Machine.Memory[Addr]))^ := Value; 271 Inc(Addr, SizeOf(SmallInt)); 272 end; 273 274 procedure TInstructionWriter.AddData32(Value: Integer); 275 begin 276 PInteger(@(Machine.Memory[Addr]))^ := Value; 277 Inc(Addr, SizeOf(Integer)); 278 end; 279 280 procedure TInstructionWriter.AddData64(Value: Int64); 281 begin 282 PInt64(@(Machine.Memory[Addr]))^ := Value; 283 Inc(Addr, SizeOf(Int64)); 284 end; 285 {$ENDIF} 140 286 141 287 { TCPU } … … 146 292 Inc(IP, SizeOf(T)); 147 293 end; 294 295 {$IFDEF EXT_LOWER_WIDTH} 296 function TCPU.ReadNext8: ShortInt; 297 begin 298 Result := PShortInt(@Memory[IP])^; 299 Inc(IP, SizeOf(ShortInt)); 300 end; 301 302 function TCPU.ReadNext16: SmallInt; 303 begin 304 Result := PSmallInt(@Memory[IP])^; 305 Inc(IP, SizeOf(SmallInt)); 306 end; 307 308 function TCPU.ReadNext32: Integer; 309 begin 310 Result := PInteger(@Memory[IP])^; 311 Inc(IP, SizeOf(Integer)); 312 end; 313 314 function TCPU.ReadNext64: Int64; 315 begin 316 Result := PInt64(@Memory[IP])^; 317 Inc(IP, SizeOf(Int64)); 318 end; 319 {$ENDIF} 148 320 149 321 function TCPU.ReadOpcode: TOpcodeIndex; … … 165 337 SP := Length(Memory); 166 338 {$ENDIF} 339 {$IFDEF EXT_LOWER_WIDTH} 340 DataWidth := dwNative; 341 {$ENDIF} 167 342 Terminated := False; 168 343 while not Terminated do … … 200 375 begin 201 376 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} 202 386 Registers[Reg] := ReadNext; 387 {$ENDIF} 203 388 end; 204 389 … … 209 394 Dest := ReadReg; 210 395 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} 211 405 Registers[Dest] := PT(@Memory[Registers[Src]])^; 406 {$ENDIF} 212 407 end; 213 408 … … 218 413 Dest := ReadReg; 219 414 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} 220 424 PT(@Memory[Registers[Dest]])^ := Registers[Src]; 425 {$ENDIF} 221 426 end; 222 427 … … 467 672 Condition := Registers[Reg2] > Registers[Reg1]; 468 673 end; 674 675 {$IFDEF EXT_LOWER_WIDTH} 676 procedure TCPU.OpcodePrefix8; 677 begin 678 DataWidth := dw8; 679 end; 680 681 procedure TCPU.OpcodePrefix16; 682 begin 683 DataWidth := dw16; 684 end; 685 686 procedure TCPU.OpcodePrefix32; 687 begin 688 DataWidth := dw32; 689 end; 690 691 procedure TCPU.OpcodePrefix64; 692 begin 693 DataWidth := dw64; 694 end; 695 {$ENDIF} 469 696 470 697 procedure TCPU.OpcodeTestNotZero; … … 520 747 end; 521 748 end; 749 {$ENDIF} 522 750 523 751 {$IFDEF EXT_BIT} … … 562 790 Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]); 563 791 end; 564 {$ENDIF}565 566 792 {$ENDIF} 567 793 … … 577 803 else raise Exception.Create('Missing handler for opcode + ' + IntToStr(Integer(Opcode))); 578 804 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} 579 810 end; 580 811
Note:
See TracChangeset
for help on using the changeset viewer.