Created
April 9, 2013 14:47
-
-
Save tangentstorm/5346279 to your computer and use it in GitHub Desktop.
RISC virtual machine by Niklaus Wirth from his book, Compiler Construction. (This is actually oberon, not pascal, but github doesn't highlight oberon)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MODULE RISC; (* NW 22.9.07 / 28.3.11 *) | |
IMPORT SYSTEM, Texts, Oberon; | |
CONST | |
MemSize = 1024; (* in words *) | |
MOV = 0; AND = 1; IOR = 2; XOR = 3; LSL = 4; ASR = 5; | |
ADD = 8; SUB = 9; MUL = 10; Div = 11; CMP = 12; | |
VAR | |
IR : LONGINT; (* instruction register *) | |
PC : LONGINT; (* program counter *) | |
N, Z : BOOLEAN; (* condition regosters *) | |
R : ARRAY 16 OF LONGINT; | |
PROCEDURE Execute*( VAR M: ARRAY OF LONGINT; VAR S: Texts.Scanner; VAR W: Texts.Writer ); | |
VAR pq, a, b, op, im : LONGINT; (* instruction fields *) | |
VAR adr, A, B, C : LONGINT; | |
BEGIN | |
PC := 0; | |
REPEAT (* interpretation cycle *) | |
IR := M[ PC ]; | |
INC( PC ); | |
pq := IR DIV 40000000H MOD 4; (* insr. class *) | |
a := IR DIV 1000000H MOD 10H; | |
b := IR DIV 100000H MOD 10H; | |
op := IR DIV 10000H MOD 10H; | |
im := IR MOD 10000H; | |
CASE pq OF | |
0, 1 : (* register instructions *) | |
B := R[ b ]; | |
IF pq = 0 THEN | |
C := R[ IR MOD 10H ] | |
ELSIF ODD( IR DIV 10000000H ) THEN | |
C := im + 0FFFF0000H | |
ELSE | |
C := im | |
END ; | |
CASE op OF | |
MOV : A := C | |
| AND : A := SYSTEM.VAL( LONGINT, SYSTEM.VAL( SET, B ) * SYSTEM.VAL( SET, C )) | |
| IOR : A := SYSTEM.VAL( LONGINT, SYSTEM.VAL( SET, B ) + SYSTEM.VAL( SET, C )) | |
| XOR : A := SYSTEM.VAL( LONGINT, SYSTEM.VAL( SET, B ) / SYSTEM.VAL( SET, C )) | |
| LSL : A := SYSTEM.LSH( B, C ) | |
| ASR : IF ODD( IR DIV 20000000H ) THEN A := SYSTEM.ROT( B, -C ) ELSE A := ASH( B, -C ) END | |
| ADD : A := B + C | |
| SUB, CMP : A := B - C | |
| MUL : A := B * C | |
| Div : A := B DIV C | |
END ; | |
IF op # CMP THEN | |
R[ a ] := A | |
END ; | |
N := A < 0; | |
Z := A = 0 | |
| 2 : (* memory instructions *) | |
adr := ( R[ b ] + IR ) MOD 100000H DIV 4; | |
IF adr < MemSize THEN | |
IF ODD( IR DIV 20000000H ) THEN | |
M[ adr ] := R[ a ] | |
ELSE | |
R[ a ] := M[ adr ] | |
END | |
ELSE (* I/O *) | |
IF ODD( IR DIV 20000000H ) THEN | |
IF adr = 3FFF2H THEN | |
Texts.WriteInt( W, R[ a ], 8 ) | |
ELSIF adr = 3FFF3H THEN | |
Texts.WriteLn( W ); | |
Texts.Append( Oberon.Log, W.buf ) | |
END | |
ELSE | |
IF adr = 3FFF2H THEN | |
Texts.Scan( S ); | |
R[ a ] := S.i | |
ELSIF adr = 3FFF3H THEN | |
IF S.class # Texts.Int THEN | |
R[ a ] := 1 | |
ELSE | |
R[ a ] := 0 | |
END | |
END | |
END | |
END ; | |
| 3 : (* branch instructions *) | |
IF ( a = 0 ) & N | |
OR ( a = 1 ) & Z | |
OR ( a = 5 ) & N | |
OR ( a = 6 ) & ( N OR Z ) | |
OR ( a = 7 ) | |
OR ( a = 8 ) & ~N | |
OR ( a = 9 ) & ~Z | |
OR ( a = 13 ) & ~N | |
OR ( a = 14 ) & ~( N OR Z ) THEN | |
IF ODD( IR DIV 10000000H ) THEN | |
R[ 15 ] := PC * 4 | |
END ; | |
IF ODD( IR DIV 20000000H ) THEN | |
PC := ( PC + ( IR MOD 1000000H )) MOD 40000H | |
ELSE | |
PC := R[ IR MOD 10H ] DIV 4 | |
END | |
END | |
END ; | |
Texts.Append( Oberon.Log, W.buf ) | |
UNTIL PC = 0 | |
END Execute; | |
END RISC. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please anyone with codes of c++,since the one here is pascal....Please help