mirror of
https://github.com/AntKrotov/oberon-07-compiler.git
synced 2026-10-05 09:45:47 +00:00
RVMxI: 32 и 64 бита
This commit is contained in:
1 parent
049d48faa9
commit
6fb87a797f
22 files changed
+1438
-166
No files matched your search
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,192 @@
|
||||
(*
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020-2021, Anton Krotov
|
||||
All rights reserved.
|
||||
*)
|
||||
|
||||
MODULE HOST;
|
||||
|
||||
IMPORT SYSTEM, Trap;
|
||||
|
||||
|
||||
CONST
|
||||
|
||||
slash* = "\";
|
||||
eol* = 0DX + 0AX;
|
||||
|
||||
bit_depth* = 64;
|
||||
maxint* = ROR(-2, 1);
|
||||
minint* = ROR(1, 1);
|
||||
|
||||
|
||||
VAR
|
||||
|
||||
maxreal*: REAL;
|
||||
|
||||
|
||||
PROCEDURE syscall0 (fn: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall0;
|
||||
|
||||
|
||||
PROCEDURE syscall1 (fn, p1: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall1;
|
||||
|
||||
|
||||
PROCEDURE syscall2 (fn, p1, p2: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall2;
|
||||
|
||||
|
||||
PROCEDURE syscall3 (fn, p1, p2, p3: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall3;
|
||||
|
||||
|
||||
PROCEDURE syscall4 (fn, p1, p2, p3, p4: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall4;
|
||||
|
||||
|
||||
PROCEDURE ExitProcess* (code: INTEGER);
|
||||
BEGIN
|
||||
code := syscall1(0, code)
|
||||
END ExitProcess;
|
||||
|
||||
|
||||
PROCEDURE GetCurrentDirectory* (VAR path: ARRAY OF CHAR);
|
||||
VAR
|
||||
a: INTEGER;
|
||||
BEGIN
|
||||
a := syscall2(1, LEN(path), SYSTEM.ADR(path[0]))
|
||||
END GetCurrentDirectory;
|
||||
|
||||
|
||||
PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR);
|
||||
BEGIN
|
||||
n := syscall3(2, n, LEN(s), SYSTEM.ADR(s[0]))
|
||||
END GetArg;
|
||||
|
||||
|
||||
PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
|
||||
RETURN syscall4(3, F, LEN(Buffer), SYSTEM.ADR(Buffer[0]), bytes)
|
||||
END FileRead;
|
||||
|
||||
|
||||
PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
|
||||
RETURN syscall4(4, F, LEN(Buffer), SYSTEM.ADR(Buffer[0]), bytes)
|
||||
END FileWrite;
|
||||
|
||||
|
||||
PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER;
|
||||
RETURN syscall2(5, LEN(FName), SYSTEM.ADR(FName[0]))
|
||||
END FileCreate;
|
||||
|
||||
|
||||
PROCEDURE FileClose* (F: INTEGER);
|
||||
BEGIN
|
||||
F := syscall1(6, F)
|
||||
END FileClose;
|
||||
|
||||
|
||||
PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER;
|
||||
RETURN syscall2(7, LEN(FName), SYSTEM.ADR(FName[0]))
|
||||
END FileOpen;
|
||||
|
||||
|
||||
PROCEDURE chmod* (FName: ARRAY OF CHAR);
|
||||
VAR
|
||||
a: INTEGER;
|
||||
BEGIN
|
||||
a := syscall2(12, LEN(FName), SYSTEM.ADR(FName[0]))
|
||||
END chmod;
|
||||
|
||||
|
||||
PROCEDURE OutChar* (c: CHAR);
|
||||
VAR
|
||||
a: INTEGER;
|
||||
BEGIN
|
||||
a := syscall1(8, ORD(c))
|
||||
END OutChar;
|
||||
|
||||
|
||||
PROCEDURE GetTickCount* (): INTEGER;
|
||||
RETURN syscall0(9)
|
||||
END GetTickCount;
|
||||
|
||||
|
||||
PROCEDURE isRelative* (path: ARRAY OF CHAR): BOOLEAN;
|
||||
RETURN syscall2(11, LEN(path), SYSTEM.ADR(path[0])) # 0
|
||||
END isRelative;
|
||||
|
||||
|
||||
PROCEDURE UnixTime* (): INTEGER;
|
||||
RETURN syscall0(10)
|
||||
END UnixTime;
|
||||
|
||||
|
||||
PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER;
|
||||
VAR
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
a := 0;
|
||||
b := 0;
|
||||
SYSTEM.GET32(SYSTEM.ADR(x), a);
|
||||
SYSTEM.GET32(SYSTEM.ADR(x) + 4, b);
|
||||
SYSTEM.GET(SYSTEM.ADR(x), res)
|
||||
RETURN res
|
||||
END splitf;
|
||||
|
||||
|
||||
PROCEDURE d2s* (x: REAL): INTEGER;
|
||||
VAR
|
||||
h, l, s, e: INTEGER;
|
||||
|
||||
BEGIN
|
||||
e := splitf(x, l, h);
|
||||
|
||||
s := ASR(h, 31) MOD 2;
|
||||
e := (h DIV 100000H) MOD 2048;
|
||||
IF e <= 896 THEN
|
||||
h := (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8 + 800000H;
|
||||
REPEAT
|
||||
h := h DIV 2;
|
||||
INC(e)
|
||||
UNTIL e = 897;
|
||||
e := 896;
|
||||
l := (h MOD 8) * 20000000H;
|
||||
h := h DIV 8
|
||||
ELSIF (1151 <= e) & (e < 2047) THEN
|
||||
e := 1151;
|
||||
h := 0;
|
||||
l := 0
|
||||
ELSIF e = 2047 THEN
|
||||
e := 1151;
|
||||
IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN
|
||||
h := 80000H;
|
||||
l := 0
|
||||
END
|
||||
END;
|
||||
DEC(e, 896)
|
||||
|
||||
RETURN LSL(s, 31) + LSL(e, 23) + (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8
|
||||
END d2s;
|
||||
|
||||
|
||||
BEGIN
|
||||
maxreal := 1.9;
|
||||
PACK(maxreal, 1023)
|
||||
END HOST.
|
||||
@@ -0,0 +1,288 @@
|
||||
(*
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2016, 2018, 2020-2021 Anton Krotov
|
||||
All rights reserved.
|
||||
*)
|
||||
|
||||
MODULE Out;
|
||||
|
||||
IMPORT HOST, SYSTEM;
|
||||
|
||||
|
||||
PROCEDURE Char* (c: CHAR);
|
||||
BEGIN
|
||||
HOST.OutChar(c)
|
||||
END Char;
|
||||
|
||||
|
||||
PROCEDURE String* (s: ARRAY OF CHAR);
|
||||
VAR
|
||||
i, n: INTEGER;
|
||||
|
||||
BEGIN
|
||||
n := LENGTH(s) - 1;
|
||||
FOR i := 0 TO n DO
|
||||
Char(s[i])
|
||||
END
|
||||
END String;
|
||||
|
||||
|
||||
PROCEDURE Int* (x, width: INTEGER);
|
||||
VAR
|
||||
i, a: INTEGER;
|
||||
str: ARRAY 21 OF CHAR;
|
||||
|
||||
BEGIN
|
||||
IF x = ROR(1, 1) THEN
|
||||
str := "-9223372036854775808";
|
||||
DEC(width, 20)
|
||||
ELSE
|
||||
i := 0;
|
||||
IF x < 0 THEN
|
||||
x := -x;
|
||||
i := 1;
|
||||
str[0] := "-"
|
||||
END;
|
||||
|
||||
a := x;
|
||||
REPEAT
|
||||
INC(i);
|
||||
a := a DIV 10
|
||||
UNTIL a = 0;
|
||||
|
||||
str[i] := 0X;
|
||||
DEC(width, i);
|
||||
|
||||
REPEAT
|
||||
DEC(i);
|
||||
str[i] := CHR(x MOD 10 + ORD("0"));
|
||||
x := x DIV 10
|
||||
UNTIL x = 0
|
||||
END;
|
||||
|
||||
WHILE width > 0 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
|
||||
String(str)
|
||||
END Int;
|
||||
|
||||
|
||||
PROCEDURE IsNan (x: REAL): BOOLEAN;
|
||||
CONST
|
||||
INF = LSR(ASR(ROR(1, 1), 10), 1);
|
||||
NINF = ASR(ASR(ROR(1, 1), 10), 1);
|
||||
|
||||
VAR
|
||||
a: INTEGER;
|
||||
|
||||
BEGIN
|
||||
SYSTEM.GET(SYSTEM.ADR(x), a)
|
||||
RETURN (a > INF) OR (a < 0) & (a > NINF)
|
||||
END IsNan;
|
||||
|
||||
|
||||
PROCEDURE Inf (x: REAL; width: INTEGER);
|
||||
VAR
|
||||
s: ARRAY 5 OF CHAR;
|
||||
|
||||
BEGIN
|
||||
DEC(width, 4);
|
||||
IF IsNan(x) THEN
|
||||
s := " Nan"
|
||||
ELSIF x = SYSTEM.INF() THEN
|
||||
s := "+Inf"
|
||||
ELSIF x = -SYSTEM.INF() THEN
|
||||
s := "-Inf"
|
||||
END;
|
||||
|
||||
WHILE width > 0 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
|
||||
String(s)
|
||||
END Inf;
|
||||
|
||||
|
||||
PROCEDURE Ln*;
|
||||
BEGIN
|
||||
Char(0DX);
|
||||
Char(0AX)
|
||||
END Ln;
|
||||
|
||||
|
||||
PROCEDURE unpk10 (VAR x: REAL; VAR n: INTEGER);
|
||||
VAR
|
||||
a, b: REAL;
|
||||
|
||||
BEGIN
|
||||
ASSERT(x > 0.0);
|
||||
n := 0;
|
||||
WHILE x < 1.0 DO
|
||||
x := x * 10.0;
|
||||
DEC(n)
|
||||
END;
|
||||
|
||||
a := 10.0;
|
||||
b := 1.0;
|
||||
|
||||
WHILE a <= x DO
|
||||
b := a;
|
||||
a := a * 10.0;
|
||||
INC(n)
|
||||
END;
|
||||
x := x / b
|
||||
END unpk10;
|
||||
|
||||
|
||||
PROCEDURE _Real (x: REAL; width: INTEGER);
|
||||
VAR
|
||||
n, k, p: INTEGER;
|
||||
|
||||
BEGIN
|
||||
p := MIN(MAX(width - 8, 1), 15);
|
||||
|
||||
width := width - p - 8;
|
||||
WHILE width > 0 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
|
||||
IF x < 0.0 THEN
|
||||
Char("-");
|
||||
x := -x
|
||||
ELSE
|
||||
Char(20X)
|
||||
END;
|
||||
|
||||
unpk10(x, n);
|
||||
|
||||
k := FLOOR(x);
|
||||
Char(CHR(k + 30H));
|
||||
Char(".");
|
||||
|
||||
WHILE p > 0 DO
|
||||
x := (x - FLT(k)) * 10.0;
|
||||
k := FLOOR(x);
|
||||
Char(CHR(k + 30H));
|
||||
DEC(p)
|
||||
END;
|
||||
|
||||
Char("E");
|
||||
IF n >= 0 THEN
|
||||
Char("+")
|
||||
ELSE
|
||||
Char("-")
|
||||
END;
|
||||
n := ABS(n);
|
||||
Char(CHR(n DIV 100 + 30H)); n := n MOD 100;
|
||||
Char(CHR(n DIV 10 + 30H));
|
||||
Char(CHR(n MOD 10 + 30H))
|
||||
END _Real;
|
||||
|
||||
|
||||
PROCEDURE Real* (x: REAL; width: INTEGER);
|
||||
BEGIN
|
||||
IF IsNan(x) OR (ABS(x) = SYSTEM.INF()) THEN
|
||||
Inf(x, width)
|
||||
ELSIF x = 0.0 THEN
|
||||
WHILE width > 23 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
DEC(width, 9);
|
||||
String(" 0.0");
|
||||
WHILE width > 0 DO
|
||||
Char("0");
|
||||
DEC(width)
|
||||
END;
|
||||
String("E+000")
|
||||
ELSE
|
||||
_Real(x, width)
|
||||
END
|
||||
END Real;
|
||||
|
||||
|
||||
PROCEDURE _FixReal (x: REAL; width, p: INTEGER);
|
||||
VAR
|
||||
n, k: INTEGER;
|
||||
minus: BOOLEAN;
|
||||
|
||||
BEGIN
|
||||
minus := x < 0.0;
|
||||
IF minus THEN
|
||||
x := -x
|
||||
END;
|
||||
|
||||
unpk10(x, n);
|
||||
|
||||
DEC(width, 3 + MAX(p, 0) + MAX(n, 0));
|
||||
WHILE width > 0 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
|
||||
IF minus THEN
|
||||
Char("-")
|
||||
ELSE
|
||||
Char(20X)
|
||||
END;
|
||||
|
||||
IF n < 0 THEN
|
||||
INC(n);
|
||||
Char("0");
|
||||
Char(".");
|
||||
WHILE (n < 0) & (p > 0) DO
|
||||
Char("0");
|
||||
INC(n);
|
||||
DEC(p)
|
||||
END
|
||||
ELSE
|
||||
WHILE n >= 0 DO
|
||||
k := FLOOR(x);
|
||||
Char(CHR(k + 30H));
|
||||
x := (x - FLT(k)) * 10.0;
|
||||
DEC(n)
|
||||
END;
|
||||
Char(".")
|
||||
END;
|
||||
|
||||
WHILE p > 0 DO
|
||||
k := FLOOR(x);
|
||||
Char(CHR(k + 30H));
|
||||
x := (x - FLT(k)) * 10.0;
|
||||
DEC(p)
|
||||
END
|
||||
|
||||
END _FixReal;
|
||||
|
||||
|
||||
PROCEDURE FixReal* (x: REAL; width, p: INTEGER);
|
||||
BEGIN
|
||||
IF IsNan(x) OR (ABS(x) = SYSTEM.INF()) THEN
|
||||
Inf(x, width)
|
||||
ELSIF x = 0.0 THEN
|
||||
DEC(width, 3 + MAX(p, 0));
|
||||
WHILE width > 0 DO
|
||||
Char(20X);
|
||||
DEC(width)
|
||||
END;
|
||||
String(" 0.");
|
||||
WHILE p > 0 DO
|
||||
Char("0");
|
||||
DEC(p)
|
||||
END
|
||||
ELSE
|
||||
_FixReal(x, width, p)
|
||||
END
|
||||
END FixReal;
|
||||
|
||||
|
||||
PROCEDURE Open*;
|
||||
END Open;
|
||||
|
||||
|
||||
END Out.
|
||||
@@ -0,0 +1,432 @@
|
||||
(*
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019-2021, Anton Krotov
|
||||
All rights reserved.
|
||||
*)
|
||||
|
||||
MODULE RTL;
|
||||
|
||||
IMPORT SYSTEM, Trap;
|
||||
|
||||
|
||||
CONST
|
||||
|
||||
bit_depth = 64;
|
||||
maxint = ROR(-2, 1);
|
||||
minint = ROR(1, 1);
|
||||
|
||||
WORD = bit_depth DIV 8;
|
||||
MAX_SET = bit_depth - 1;
|
||||
|
||||
|
||||
VAR
|
||||
|
||||
Heap, Types, TypesCount: INTEGER;
|
||||
|
||||
|
||||
PROCEDURE _error* (modnum, _module, err, line: INTEGER);
|
||||
BEGIN
|
||||
Trap.trap(modnum, _module, err, line)
|
||||
END _error;
|
||||
|
||||
|
||||
PROCEDURE syscall1 (fn, p1: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall1;
|
||||
|
||||
|
||||
PROCEDURE syscall2 (fn, p1, p2: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall2;
|
||||
|
||||
|
||||
PROCEDURE syscall3 (fn, p1, p2, p3: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
Trap.syscall(SYSTEM.ADR(fn))
|
||||
RETURN fn
|
||||
END syscall3;
|
||||
|
||||
|
||||
PROCEDURE _fmul* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(100, b, a)
|
||||
END _fmul;
|
||||
|
||||
|
||||
PROCEDURE _fdiv* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(101, b, a)
|
||||
END _fdiv;
|
||||
|
||||
|
||||
PROCEDURE _fdivi* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(101, a, b)
|
||||
END _fdivi;
|
||||
|
||||
|
||||
PROCEDURE _fadd* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(102, b, a)
|
||||
END _fadd;
|
||||
|
||||
|
||||
PROCEDURE _fsub* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(103, b, a)
|
||||
END _fsub;
|
||||
|
||||
|
||||
PROCEDURE _fsubi* (b, a: INTEGER): INTEGER;
|
||||
RETURN syscall2(103, a, b)
|
||||
END _fsubi;
|
||||
|
||||
|
||||
PROCEDURE _fcmp* (op, b, a: INTEGER): BOOLEAN;
|
||||
RETURN syscall3(104, op, b, a) # 0
|
||||
END _fcmp;
|
||||
|
||||
|
||||
PROCEDURE _floor* (x: INTEGER): INTEGER;
|
||||
RETURN syscall1(105, x)
|
||||
END _floor;
|
||||
|
||||
|
||||
PROCEDURE _flt* (x: INTEGER): INTEGER;
|
||||
RETURN syscall1(106, x)
|
||||
END _flt;
|
||||
|
||||
|
||||
PROCEDURE _pack* (n: INTEGER; VAR x: SET);
|
||||
BEGIN
|
||||
n := LSL((LSR(ORD(x), 52) MOD 2048 + n) MOD 2048, 52);
|
||||
x := x - {52..62} + BITS(n)
|
||||
END _pack;
|
||||
|
||||
|
||||
PROCEDURE _unpk* (VAR n: INTEGER; VAR x: SET);
|
||||
BEGIN
|
||||
n := LSR(ORD(x), 52) MOD 2048 - 1023;
|
||||
x := x - {62} + {52..61}
|
||||
END _unpk;
|
||||
|
||||
|
||||
PROCEDURE _rot* (VAR A: ARRAY OF INTEGER);
|
||||
VAR
|
||||
i, n, k: INTEGER;
|
||||
|
||||
BEGIN
|
||||
k := LEN(A) - 1;
|
||||
n := A[0];
|
||||
i := 0;
|
||||
WHILE i < k DO
|
||||
A[i] := A[i + 1];
|
||||
INC(i)
|
||||
END;
|
||||
A[k] := n
|
||||
END _rot;
|
||||
|
||||
|
||||
PROCEDURE _set* (b, a: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
IF (a <= b) & (a <= MAX_SET) & (b >= 0) THEN
|
||||
IF b > MAX_SET THEN
|
||||
b := MAX_SET
|
||||
END;
|
||||
IF a < 0 THEN
|
||||
a := 0
|
||||
END;
|
||||
a := LSR(ASR(minint, b - a), MAX_SET - b)
|
||||
ELSE
|
||||
a := 0
|
||||
END
|
||||
|
||||
RETURN a
|
||||
END _set;
|
||||
|
||||
|
||||
PROCEDURE _set1* (a: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
IF ASR(a, 6) = 0 THEN
|
||||
a := LSL(1, a)
|
||||
ELSE
|
||||
a := 0
|
||||
END
|
||||
RETURN a
|
||||
END _set1;
|
||||
|
||||
|
||||
PROCEDURE _length* (len, str: INTEGER): INTEGER;
|
||||
VAR
|
||||
c: CHAR;
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
res := 0;
|
||||
REPEAT
|
||||
SYSTEM.GET(str, c);
|
||||
INC(str);
|
||||
DEC(len);
|
||||
INC(res)
|
||||
UNTIL (len = 0) OR (c = 0X);
|
||||
|
||||
RETURN res - ORD(c = 0X)
|
||||
END _length;
|
||||
|
||||
|
||||
PROCEDURE _move* (bytes, dest, source: INTEGER);
|
||||
VAR
|
||||
b: BYTE;
|
||||
i: INTEGER;
|
||||
|
||||
BEGIN
|
||||
IF (source MOD WORD = 0) & (dest MOD WORD = 0) THEN
|
||||
WHILE bytes >= WORD DO
|
||||
SYSTEM.GET(source, i);
|
||||
SYSTEM.PUT(dest, i);
|
||||
INC(source, WORD);
|
||||
INC(dest, WORD);
|
||||
DEC(bytes, WORD)
|
||||
END
|
||||
END;
|
||||
|
||||
WHILE bytes > 0 DO
|
||||
SYSTEM.GET(source, b);
|
||||
SYSTEM.PUT8(dest, b);
|
||||
INC(source);
|
||||
INC(dest);
|
||||
DEC(bytes)
|
||||
END
|
||||
END _move;
|
||||
|
||||
|
||||
PROCEDURE _lengthw* (len, str: INTEGER): INTEGER;
|
||||
VAR
|
||||
c: WCHAR;
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
res := 0;
|
||||
REPEAT
|
||||
SYSTEM.GET(str, c);
|
||||
INC(str, 2);
|
||||
DEC(len);
|
||||
INC(res)
|
||||
UNTIL (len = 0) OR (c = 0X);
|
||||
|
||||
RETURN res - ORD(c = 0X)
|
||||
END _lengthw;
|
||||
|
||||
|
||||
PROCEDURE strncmp (a, b, n: INTEGER): INTEGER;
|
||||
VAR
|
||||
A, B: CHAR;
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
res := minint;
|
||||
WHILE n > 0 DO
|
||||
SYSTEM.GET(a, A); INC(a);
|
||||
SYSTEM.GET(b, B); INC(b);
|
||||
DEC(n);
|
||||
IF A # B THEN
|
||||
res := ORD(A) - ORD(B);
|
||||
n := 0
|
||||
ELSIF A = 0X THEN
|
||||
res := 0;
|
||||
n := 0
|
||||
END
|
||||
END
|
||||
RETURN res
|
||||
END strncmp;
|
||||
|
||||
|
||||
PROCEDURE _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
res: INTEGER;
|
||||
bRes: BOOLEAN;
|
||||
c: CHAR;
|
||||
|
||||
BEGIN
|
||||
res := strncmp(str1, str2, MIN(len1, len2));
|
||||
IF res = minint THEN
|
||||
IF len1 > len2 THEN
|
||||
SYSTEM.GET(str1 + len2, c);
|
||||
res := ORD(c)
|
||||
ELSIF len1 < len2 THEN
|
||||
SYSTEM.GET(str2 + len1, c);
|
||||
res := -ORD(c)
|
||||
ELSE
|
||||
res := 0
|
||||
END
|
||||
END;
|
||||
|
||||
CASE op OF
|
||||
|0: bRes := res = 0
|
||||
|1: bRes := res # 0
|
||||
|2: bRes := res < 0
|
||||
|3: bRes := res <= 0
|
||||
|4: bRes := res > 0
|
||||
|5: bRes := res >= 0
|
||||
END
|
||||
|
||||
RETURN bRes
|
||||
END _strcmp;
|
||||
|
||||
|
||||
PROCEDURE strncmpw (a, b, n: INTEGER): INTEGER;
|
||||
VAR
|
||||
A, B: WCHAR;
|
||||
res: INTEGER;
|
||||
|
||||
BEGIN
|
||||
res := minint;
|
||||
WHILE n > 0 DO
|
||||
SYSTEM.GET(a, A); INC(a, 2);
|
||||
SYSTEM.GET(b, B); INC(b, 2);
|
||||
DEC(n);
|
||||
IF A # B THEN
|
||||
res := ORD(A) - ORD(B);
|
||||
n := 0
|
||||
ELSIF A = 0X THEN
|
||||
res := 0;
|
||||
n := 0
|
||||
END
|
||||
END
|
||||
RETURN res
|
||||
END strncmpw;
|
||||
|
||||
|
||||
PROCEDURE _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
res: INTEGER;
|
||||
bRes: BOOLEAN;
|
||||
c: WCHAR;
|
||||
|
||||
BEGIN
|
||||
res := strncmpw(str1, str2, MIN(len1, len2));
|
||||
IF res = minint THEN
|
||||
IF len1 > len2 THEN
|
||||
SYSTEM.GET(str1 + len2 * 2, c);
|
||||
res := ORD(c)
|
||||
ELSIF len1 < len2 THEN
|
||||
SYSTEM.GET(str2 + len1 * 2, c);
|
||||
res := -ORD(c)
|
||||
ELSE
|
||||
res := 0
|
||||
END
|
||||
END;
|
||||
|
||||
CASE op OF
|
||||
|0: bRes := res = 0
|
||||
|1: bRes := res # 0
|
||||
|2: bRes := res < 0
|
||||
|3: bRes := res <= 0
|
||||
|4: bRes := res > 0
|
||||
|5: bRes := res >= 0
|
||||
END
|
||||
|
||||
RETURN bRes
|
||||
END _strcmpw;
|
||||
|
||||
|
||||
PROCEDURE _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
res: BOOLEAN;
|
||||
|
||||
BEGIN
|
||||
IF len_src > len_dst THEN
|
||||
res := FALSE
|
||||
ELSE
|
||||
_move(len_src * base_size, dst, src);
|
||||
res := TRUE
|
||||
END
|
||||
|
||||
RETURN res
|
||||
END _arrcpy;
|
||||
|
||||
|
||||
PROCEDURE _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER);
|
||||
BEGIN
|
||||
_move(MIN(len_dst, len_src) * chr_size, dst, src)
|
||||
END _strcpy;
|
||||
|
||||
|
||||
PROCEDURE _new* (t, size: INTEGER; VAR p: INTEGER);
|
||||
VAR
|
||||
ptr: INTEGER;
|
||||
|
||||
BEGIN
|
||||
ptr := Heap;
|
||||
IF ptr + size < Trap.sp() - 128 THEN
|
||||
INC(Heap, size);
|
||||
p := ptr + WORD;
|
||||
SYSTEM.PUT(ptr, t);
|
||||
INC(ptr, WORD);
|
||||
DEC(size, WORD);
|
||||
WHILE size > 0 DO
|
||||
SYSTEM.PUT(ptr, 0);
|
||||
INC(ptr, WORD);
|
||||
DEC(size, WORD)
|
||||
END
|
||||
ELSE
|
||||
p := 0
|
||||
END
|
||||
END _new;
|
||||
|
||||
|
||||
PROCEDURE _guard* (t, p: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
_type: INTEGER;
|
||||
|
||||
BEGIN
|
||||
SYSTEM.GET(p, p);
|
||||
IF p # 0 THEN
|
||||
SYSTEM.GET(p - WORD, _type);
|
||||
WHILE (_type # t) & (_type # 0) DO
|
||||
SYSTEM.GET(Types + _type * WORD, _type)
|
||||
END
|
||||
ELSE
|
||||
_type := t
|
||||
END
|
||||
|
||||
RETURN _type = t
|
||||
END _guard;
|
||||
|
||||
|
||||
PROCEDURE _is* (t, p: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
_type: INTEGER;
|
||||
|
||||
BEGIN
|
||||
_type := 0;
|
||||
IF p # 0 THEN
|
||||
SYSTEM.GET(p - WORD, _type);
|
||||
WHILE (_type # t) & (_type # 0) DO
|
||||
SYSTEM.GET(Types + _type * WORD, _type)
|
||||
END
|
||||
END
|
||||
|
||||
RETURN _type = t
|
||||
END _is;
|
||||
|
||||
|
||||
PROCEDURE _guardrec* (t0, t1: INTEGER): BOOLEAN;
|
||||
BEGIN
|
||||
WHILE (t1 # t0) & (t1 # 0) DO
|
||||
SYSTEM.GET(Types + t1 * WORD, t1)
|
||||
END
|
||||
|
||||
RETURN t1 = t0
|
||||
END _guardrec;
|
||||
|
||||
|
||||
PROCEDURE _init* (tcount, heap, types: INTEGER);
|
||||
BEGIN
|
||||
Heap := heap;
|
||||
TypesCount := tcount;
|
||||
Types := types
|
||||
END _init;
|
||||
|
||||
|
||||
END RTL.
|
||||
@@ -0,0 +1,133 @@
|
||||
(*
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020-2021, Anton Krotov
|
||||
All rights reserved.
|
||||
*)
|
||||
|
||||
MODULE Trap;
|
||||
|
||||
IMPORT SYSTEM;
|
||||
|
||||
|
||||
CONST
|
||||
|
||||
SP = 4;
|
||||
|
||||
|
||||
PROCEDURE [code] sp* (): INTEGER
|
||||
22, 0, SP; (* MOV R0, SP *)
|
||||
|
||||
|
||||
PROCEDURE [code] syscall* (ptr: INTEGER)
|
||||
22, 0, SP, (* MOV R0, SP *)
|
||||
27, 0, 8, (* ADD R0, 8 *)
|
||||
16, 0, 0, (* LDD R0, R0 *)
|
||||
67, 0, 0; (* SYSCALL R0 *)
|
||||
|
||||
|
||||
PROCEDURE Char (c: CHAR);
|
||||
VAR
|
||||
a: ARRAY 2 OF INTEGER;
|
||||
|
||||
BEGIN
|
||||
a[0] := 8;
|
||||
a[1] := ORD(c);
|
||||
syscall(SYSTEM.ADR(a[0]))
|
||||
END Char;
|
||||
|
||||
|
||||
PROCEDURE String (s: ARRAY OF CHAR);
|
||||
VAR
|
||||
i: INTEGER;
|
||||
|
||||
BEGIN
|
||||
i := 0;
|
||||
WHILE s[i] # 0X DO
|
||||
Char(s[i]);
|
||||
INC(i)
|
||||
END
|
||||
END String;
|
||||
|
||||
|
||||
PROCEDURE PString (ptr: INTEGER);
|
||||
VAR
|
||||
c: CHAR;
|
||||
|
||||
BEGIN
|
||||
SYSTEM.GET(ptr, c);
|
||||
WHILE c # 0X DO
|
||||
Char(c);
|
||||
INC(ptr);
|
||||
SYSTEM.GET(ptr, c)
|
||||
END
|
||||
END PString;
|
||||
|
||||
|
||||
PROCEDURE Ln;
|
||||
BEGIN
|
||||
String(0DX + 0AX)
|
||||
END Ln;
|
||||
|
||||
|
||||
PROCEDURE IntToStr (x: INTEGER; VAR str: ARRAY OF CHAR);
|
||||
VAR
|
||||
i, a: INTEGER;
|
||||
|
||||
BEGIN
|
||||
i := 0;
|
||||
a := x;
|
||||
REPEAT
|
||||
INC(i);
|
||||
a := a DIV 10
|
||||
UNTIL a = 0;
|
||||
|
||||
str[i] := 0X;
|
||||
|
||||
REPEAT
|
||||
DEC(i);
|
||||
str[i] := CHR(x MOD 10 + ORD("0"));
|
||||
x := x DIV 10
|
||||
UNTIL x = 0
|
||||
END IntToStr;
|
||||
|
||||
|
||||
PROCEDURE Int (x: INTEGER);
|
||||
VAR
|
||||
s: ARRAY 32 OF CHAR;
|
||||
|
||||
BEGIN
|
||||
IntToStr(x, s);
|
||||
String(s)
|
||||
END Int;
|
||||
|
||||
|
||||
PROCEDURE trap* (modnum, _module, err, line: INTEGER);
|
||||
VAR
|
||||
s: ARRAY 32 OF CHAR;
|
||||
|
||||
BEGIN
|
||||
CASE err OF
|
||||
| 1: s := "assertion failure"
|
||||
| 2: s := "NIL dereference"
|
||||
| 3: s := "bad divisor"
|
||||
| 4: s := "NIL procedure call"
|
||||
| 5: s := "type guard error"
|
||||
| 6: s := "index out of range"
|
||||
| 7: s := "invalid CASE"
|
||||
| 8: s := "array assignment error"
|
||||
| 9: s := "CHR out of range"
|
||||
|10: s := "WCHR out of range"
|
||||
|11: s := "BYTE out of range"
|
||||
END;
|
||||
|
||||
Ln;
|
||||
String("error ("); Int(err); String("): "); String(s); Ln;
|
||||
String("module: "); PString(_module); Ln;
|
||||
String("line: "); Int(line); Ln;
|
||||
|
||||
SYSTEM.CODE(0, 0, 0) (* STOP *)
|
||||
END trap;
|
||||
|
||||
|
||||
END Trap.
|
||||
@@ -0,0 +1,5 @@
|
||||
Compiler.exe ./tools/RVMxI.ob07 win32con -nochk a -out RVM32I.exe
|
||||
Compiler.exe source\Compiler.ob07 rvm32i -out Compiler32.bin -lower
|
||||
RVM32I.exe Compiler32.bin -dis Compiler32.txt
|
||||
RVM32I.exe Compiler32.bin -run source\Compiler.ob07 rvm32i -out Compiler32.bin -lower
|
||||
@pause
|
||||
@@ -0,0 +1,5 @@
|
||||
Compiler.exe ./tools/RVMxI.ob07 win64con -nochk a -out RVM64I.exe
|
||||
Compiler.exe source\Compiler.ob07 rvm64i -out Compiler64.bin -lower
|
||||
RVM64I.exe Compiler64.bin -dis Compiler64.txt
|
||||
RVM64I.exe Compiler64.bin -run source\Compiler.ob07 rvm64i -out Compiler64.bin -lower
|
||||
@pause
|
||||
@@ -311,6 +311,7 @@ BEGIN
|
||||
|TARGETS.cpuMSP430:
|
||||
|TARGETS.cpuTHUMB:
|
||||
|TARGETS.cpuRVM32I:
|
||||
|TARGETS.cpuRVM64I:
|
||||
END;
|
||||
|
||||
ST.compile(path, lib_path, modname, outname, target, options);
|
||||
|
||||
+1
-1
@@ -502,7 +502,7 @@ BEGIN
|
||||
old_opcode := -1
|
||||
END
|
||||
|
||||
ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I} THEN
|
||||
ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
|
||||
|
||||
old_opcode := cur.opcode;
|
||||
param2 := nov.param2;
|
||||
|
||||
+5
-1
@@ -668,7 +668,11 @@ BEGIN
|
||||
ELSE
|
||||
call := PROG.cdecl
|
||||
END
|
||||
|64: call := PROG.default64
|
||||
|64: IF TARGETS.CPU = TARGETS.cpuAMD64 THEN
|
||||
call := PROG.default64
|
||||
ELSE
|
||||
call := PROG.cdecl
|
||||
END
|
||||
END
|
||||
END;
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
All rights reserved.
|
||||
*)
|
||||
|
||||
MODULE RVM32I;
|
||||
MODULE RVMxI;
|
||||
|
||||
IMPORT
|
||||
|
||||
PROG, WR := WRITER, IL, CHL := CHUNKLISTS, REG, UTILS, STRINGS, ERRORS;
|
||||
PROG, WR := WRITER, IL, CHL := CHUNKLISTS, REG, UTILS, STRINGS, ERRORS, TARGETS;
|
||||
|
||||
|
||||
CONST
|
||||
@@ -31,16 +31,17 @@ CONST
|
||||
|
||||
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opNOP = 5;
|
||||
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
|
||||
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15; (* 16, 17, 18 *)
|
||||
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15;
|
||||
opLDD = 16; (* 17, 18 *)
|
||||
opJMP = 19; opCALL = 20; opCALLI = 21;
|
||||
|
||||
opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
|
||||
opSTB = 34; opSTH = 36; opSTW = 38; (* 40, 42, 44 *)
|
||||
opSTB = 34; opSTH = 36; opSTW = 38; opSTD = 40; (* 42, 44 *)
|
||||
opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
|
||||
opLSL = 56; opROR = 58; (* 60, 62 *) opCMP = 64;
|
||||
|
||||
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
|
||||
opSTBC = 35; opSTHC = 37; opSTWC = 39; (* 41, 43, 45 *)
|
||||
opSTBC = 35; opSTHC = 37; opSTWC = 39; opSTDC = 41; (* 43, 45 *)
|
||||
opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
|
||||
opLSLC = 57; opRORC = 59; (* 61, 63 *) opCMPC = 65;
|
||||
|
||||
@@ -49,12 +50,12 @@ CONST
|
||||
opJEQ = 70; opJNE = 71; opJLT = 72; opJGE = 73; opJGT = 74; opJLE = 75;
|
||||
opSEQ = 76; opSNE = 77; opSLT = 78; opSGE = 79; opSGT = 80; opSLE = 81;
|
||||
|
||||
inf = 7F800000H;
|
||||
|
||||
|
||||
VAR
|
||||
|
||||
R: REG.REGS; count: INTEGER;
|
||||
R: REG.REGS; count, szWord: INTEGER;
|
||||
|
||||
ldr, str: PROCEDURE (r1, r2: INTEGER);
|
||||
|
||||
|
||||
PROCEDURE OutByte (n: BYTE);
|
||||
@@ -66,8 +67,13 @@ END OutByte;
|
||||
|
||||
PROCEDURE OutInt (n: INTEGER);
|
||||
BEGIN
|
||||
WR.Write32LE(n);
|
||||
INC(count, 4)
|
||||
IF szWord = 8 THEN
|
||||
WR.Write64LE(n);
|
||||
INC(count, 8)
|
||||
ELSE (* szWord = 4 *)
|
||||
WR.Write32LE(n);
|
||||
INC(count, 4)
|
||||
END
|
||||
END OutInt;
|
||||
|
||||
|
||||
@@ -175,6 +181,12 @@ BEGIN
|
||||
END sub;
|
||||
|
||||
|
||||
PROCEDURE ldr64 (r1, r2: INTEGER);
|
||||
BEGIN
|
||||
Emit(opLDD, r2 * 256 + r1, 0)
|
||||
END ldr64;
|
||||
|
||||
|
||||
PROCEDURE ldr32 (r1, r2: INTEGER);
|
||||
BEGIN
|
||||
Emit(opLDW, r2 * 256 + r1, 0)
|
||||
@@ -193,6 +205,12 @@ BEGIN
|
||||
END ldr8;
|
||||
|
||||
|
||||
PROCEDURE str64 (r1, r2: INTEGER);
|
||||
BEGIN
|
||||
Emit(opSTD, r1 * 256 + r2, 0)
|
||||
END str64;
|
||||
|
||||
|
||||
PROCEDURE str32 (r1, r2: INTEGER);
|
||||
BEGIN
|
||||
Emit(opSTW, r1 * 256 + r2, 0)
|
||||
@@ -239,7 +257,7 @@ END jnz;
|
||||
PROCEDURE CallRTL (proc, par: INTEGER);
|
||||
BEGIN
|
||||
Emit(opCALL, IL.codes.rtl[proc], 0);
|
||||
addrc(SP, par * 4)
|
||||
addrc(SP, par * szWord)
|
||||
END CallRTL;
|
||||
|
||||
|
||||
@@ -282,14 +300,24 @@ BEGIN
|
||||
END shift;
|
||||
|
||||
|
||||
PROCEDURE translate;
|
||||
PROCEDURE translate (szWord: INTEGER);
|
||||
VAR
|
||||
cmd, next: IL.COMMAND;
|
||||
opcode, param1, param2: INTEGER;
|
||||
r1, r2, r3: INTEGER;
|
||||
label: INTEGER;
|
||||
|
||||
opcode, param1, param2, r1, r2, r3,
|
||||
a, b, label, opLD, opST, opSTC: INTEGER;
|
||||
|
||||
BEGIN
|
||||
IF szWord = 8 THEN
|
||||
opLD := opLDD;
|
||||
opST := opSTD;
|
||||
opSTC := opSTDC
|
||||
ELSE
|
||||
opLD := opLDW;
|
||||
opST := opSTW;
|
||||
opSTC := opSTWC
|
||||
END;
|
||||
|
||||
cmd := IL.codes.commands.first(IL.COMMAND);
|
||||
|
||||
WHILE cmd # NIL DO
|
||||
@@ -320,7 +348,7 @@ BEGIN
|
||||
|
||||
|IL.opCLEANUP:
|
||||
IF param2 # 0 THEN
|
||||
addrc(SP, param2 * 4)
|
||||
addrc(SP, param2 * szWord)
|
||||
END
|
||||
|
||||
|IL.opNOP, IL.opAND, IL.opOR:
|
||||
@@ -332,24 +360,30 @@ BEGIN
|
||||
GlobalAdr(GetAnyReg(), param2)
|
||||
|
||||
|IL.opLADR:
|
||||
param2 := param2 * szWord;
|
||||
next := cmd.next(IL.COMMAND);
|
||||
IF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE32) OR (next.opcode = IL.opSAVEF) THEN
|
||||
IF ((next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVEF)) & (szWord = 8) OR (next.opcode = IL.opSAVE64) THEN
|
||||
UnOp(r1);
|
||||
Emit(opSTW, BP * 256 + r1, param2 * 4);
|
||||
Emit(opSTD, BP * 256 + r1, param2);
|
||||
drop;
|
||||
cmd := next
|
||||
ELSIF ((next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVEF)) & (szWord = 4) OR (next.opcode = IL.opSAVE32) THEN
|
||||
UnOp(r1);
|
||||
Emit(opSTW, BP * 256 + r1, param2);
|
||||
drop;
|
||||
cmd := next
|
||||
ELSIF next.opcode = IL.opSAVE16 THEN
|
||||
UnOp(r1);
|
||||
Emit(opSTH, BP * 256 + r1, param2 * 4);
|
||||
Emit(opSTH, BP * 256 + r1, param2);
|
||||
drop;
|
||||
cmd := next
|
||||
ELSIF next.opcode = IL.opSAVE8 THEN
|
||||
UnOp(r1);
|
||||
Emit(opSTB, BP * 256 + r1, param2 * 4);
|
||||
Emit(opSTB, BP * 256 + r1, param2);
|
||||
drop;
|
||||
cmd := next
|
||||
ELSE
|
||||
Emit(opADDRC, BP * 256 + GetAnyReg(), param2 * 4)
|
||||
Emit(opADDRC, BP * 256 + GetAnyReg(), param2)
|
||||
END
|
||||
|
||||
|IL.opPARAM:
|
||||
@@ -415,7 +449,7 @@ BEGIN
|
||||
|
||||
|IL.opSAVEC:
|
||||
UnOp(r1);
|
||||
Emit(opSTWC, r1, param2);
|
||||
Emit(opSTC, r1, param2);
|
||||
drop
|
||||
|
||||
|IL.opSAVE8C:
|
||||
@@ -428,15 +462,27 @@ BEGIN
|
||||
Emit(opSTHC, r1, param2 MOD 65536);
|
||||
drop
|
||||
|
||||
|IL.opSAVE, IL.opSAVE32, IL.opSAVEF:
|
||||
|IL.opSAVE, IL.opSAVEF:
|
||||
BinOp(r2, r1);
|
||||
str(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
|IL.opSAVE32:
|
||||
BinOp(r2, r1);
|
||||
str32(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
|IL.opSAVE64:
|
||||
BinOp(r2, r1);
|
||||
str64(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
|IL.opSAVEFI:
|
||||
BinOp(r2, r1);
|
||||
str32(r2, r1);
|
||||
str(r2, r1);
|
||||
drop;
|
||||
drop
|
||||
|
||||
@@ -457,25 +503,41 @@ BEGIN
|
||||
GlobalAdr(r1, param2);
|
||||
ldr32(r1, r1)
|
||||
|
||||
|IL.opVADR, IL.opLLOAD32:
|
||||
Emit(opLDW, BP * 256 + GetAnyReg(), param2 * 4)
|
||||
|IL.opGLOAD64:
|
||||
r1 := GetAnyReg();
|
||||
GlobalAdr(r1, param2);
|
||||
ldr64(r1, r1)
|
||||
|
||||
|IL.opVADR:
|
||||
Emit(opLD, BP * 256 + GetAnyReg(), param2 * szWord)
|
||||
|
||||
|IL.opLLOAD32:
|
||||
Emit(opLDW, BP * 256 + GetAnyReg(), param2 * szWord)
|
||||
|
||||
|IL.opLLOAD64:
|
||||
Emit(opLDD, BP * 256 + GetAnyReg(), param2 * szWord)
|
||||
|
||||
|IL.opVLOAD32:
|
||||
r1 := GetAnyReg();
|
||||
Emit(opLDW, BP * 256 + r1, param2 * 4);
|
||||
Emit(opLD, BP * 256 + r1, param2 * szWord);
|
||||
ldr32(r1, r1)
|
||||
|
||||
|IL.opVLOAD64:
|
||||
r1 := GetAnyReg();
|
||||
Emit(opLDD, BP * 256 + r1, param2 * szWord);
|
||||
ldr64(r1, r1)
|
||||
|
||||
|IL.opGLOAD16:
|
||||
r1 := GetAnyReg();
|
||||
GlobalAdr(r1, param2);
|
||||
ldr16(r1, r1)
|
||||
|
||||
|IL.opLLOAD16:
|
||||
Emit(opLDH, BP * 256 + GetAnyReg(), param2 * 4)
|
||||
Emit(opLDH, BP * 256 + GetAnyReg(), param2 * szWord)
|
||||
|
||||
|IL.opVLOAD16:
|
||||
r1 := GetAnyReg();
|
||||
Emit(opLDW, BP * 256 + r1, param2 * 4);
|
||||
Emit(opLD, BP * 256 + r1, param2 * szWord);
|
||||
ldr16(r1, r1)
|
||||
|
||||
|IL.opGLOAD8:
|
||||
@@ -484,11 +546,11 @@ BEGIN
|
||||
ldr8(r1, r1)
|
||||
|
||||
|IL.opLLOAD8:
|
||||
Emit(opLDB, BP * 256 + GetAnyReg(), param2 * 4)
|
||||
Emit(opLDB, BP * 256 + GetAnyReg(), param2 * szWord)
|
||||
|
||||
|IL.opVLOAD8:
|
||||
r1 := GetAnyReg();
|
||||
Emit(opLDW, BP * 256 + r1, param2 * 4);
|
||||
Emit(opLD, BP * 256 + r1, param2 * szWord);
|
||||
ldr8(r1, r1)
|
||||
|
||||
|IL.opLOAD8:
|
||||
@@ -499,10 +561,18 @@ BEGIN
|
||||
UnOp(r1);
|
||||
ldr16(r1, r1)
|
||||
|
||||
|IL.opLOAD32, IL.opLOADF:
|
||||
|IL.opLOAD32:
|
||||
UnOp(r1);
|
||||
ldr32(r1, r1)
|
||||
|
||||
|IL.opLOAD64:
|
||||
UnOp(r1);
|
||||
ldr64(r1, r1)
|
||||
|
||||
|IL.opLOADF:
|
||||
UnOp(r1);
|
||||
ldr(r1, r1)
|
||||
|
||||
|IL.opLOOP, IL.opENDLOOP:
|
||||
|
||||
|IL.opUMINUS:
|
||||
@@ -523,7 +593,13 @@ BEGIN
|
||||
UnOp(r1);
|
||||
next := cmd.next(IL.COMMAND);
|
||||
CASE next.opcode OF
|
||||
|IL.opLOAD32, IL.opLOADF:
|
||||
|IL.opLOADF:
|
||||
Emit(opLD, r1 * 256 + r1, param2);
|
||||
cmd := next
|
||||
|IL.opLOAD64:
|
||||
Emit(opLDD, r1 * 256 + r1, param2);
|
||||
cmd := next
|
||||
|IL.opLOAD32:
|
||||
Emit(opLDW, r1 * 256 + r1, param2);
|
||||
cmd := next
|
||||
|IL.opLOAD16:
|
||||
@@ -702,19 +778,19 @@ BEGIN
|
||||
|
||||
|IL.opASR2:
|
||||
UnOp(r1);
|
||||
Emit(opASRC, r1, param2 MOD 32)
|
||||
Emit(opASRC, r1, param2 MOD (szWord * 8))
|
||||
|
||||
|IL.opLSL2:
|
||||
UnOp(r1);
|
||||
Emit(opLSLC, r1, param2 MOD 32)
|
||||
Emit(opLSLC, r1, param2 MOD (szWord * 8))
|
||||
|
||||
|IL.opROR2:
|
||||
UnOp(r1);
|
||||
Emit(opRORC, r1, param2 MOD 32)
|
||||
Emit(opRORC, r1, param2 MOD (szWord * 8))
|
||||
|
||||
|IL.opLSR2:
|
||||
UnOp(r1);
|
||||
Emit(opLSRC, r1, param2 MOD 32)
|
||||
Emit(opLSRC, r1, param2 MOD (szWord * 8))
|
||||
|
||||
|IL.opCHR:
|
||||
UnOp(r1);
|
||||
@@ -795,9 +871,9 @@ BEGIN
|
||||
|IL.opINCC:
|
||||
UnOp(r1);
|
||||
r2 := GetAnyReg();
|
||||
ldr32(r2, r1);
|
||||
ldr(r2, r1);
|
||||
addrc(r2, param2);
|
||||
str32(r1, r2);
|
||||
str(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
@@ -830,13 +906,13 @@ BEGIN
|
||||
|IL.opINC, IL.opDEC:
|
||||
BinOp(r2, r1);
|
||||
r3 := GetAnyReg();
|
||||
ldr32(r3, r1);
|
||||
ldr(r3, r1);
|
||||
IF opcode = IL.opINC THEN
|
||||
add(r3, r2)
|
||||
ELSE
|
||||
sub(r3, r2)
|
||||
END;
|
||||
str32(r1, r3);
|
||||
str(r1, r3);
|
||||
drop;
|
||||
drop;
|
||||
drop
|
||||
@@ -845,14 +921,14 @@ BEGIN
|
||||
BinOp(r2, r1);
|
||||
Emit(opBIT, r2, r2);
|
||||
r3 := GetAnyReg();
|
||||
ldr32(r3, r1);
|
||||
ldr(r3, r1);
|
||||
IF opcode = IL.opINCL THEN
|
||||
Emit(opOR, r3, r2)
|
||||
ELSE
|
||||
Emit(opNOT, r2, 0);
|
||||
Emit(opAND, r3, r2)
|
||||
END;
|
||||
str32(r1, r3);
|
||||
str(r1, r3);
|
||||
drop;
|
||||
drop;
|
||||
drop
|
||||
@@ -860,13 +936,13 @@ BEGIN
|
||||
|IL.opINCLC, IL.opEXCLC:
|
||||
UnOp(r1);
|
||||
r2 := GetAnyReg();
|
||||
ldr32(r2, r1);
|
||||
ldr(r2, r1);
|
||||
IF opcode = IL.opINCLC THEN
|
||||
Emit(opORC, r2, ORD({param2}))
|
||||
ELSE
|
||||
Emit(opANDC, r2, ORD(-{param2}))
|
||||
END;
|
||||
str32(r1, r2);
|
||||
str(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
@@ -919,7 +995,7 @@ BEGIN
|
||||
UnOp(r1);
|
||||
r2 := GetAnyReg();
|
||||
ProcAdr(r2, param2);
|
||||
str32(r1, r2);
|
||||
str(r1, r2);
|
||||
drop;
|
||||
drop
|
||||
|
||||
@@ -928,7 +1004,7 @@ BEGIN
|
||||
|
||||
|IL.opPUSHT:
|
||||
UnOp(r1);
|
||||
Emit(opLDW, r1 * 256 + GetAnyReg(), -4)
|
||||
Emit(opLD, r1 * 256 + GetAnyReg(), -szWord)
|
||||
|
||||
|IL.opGET, IL.opGETC:
|
||||
IF opcode = IL.opGET THEN
|
||||
@@ -945,6 +1021,7 @@ BEGIN
|
||||
|1: ldr8(r1, r1); str8(r2, r1)
|
||||
|2: ldr16(r1, r1); str16(r2, r1)
|
||||
|4: ldr32(r1, r1); str32(r2, r1)
|
||||
|8: ldr64(r1, r1); str64(r2, r1)
|
||||
END
|
||||
|
||||
|IL.opNOT:
|
||||
@@ -1094,8 +1171,8 @@ BEGIN
|
||||
|
||||
|IL.opNEW:
|
||||
PushAll(1);
|
||||
INC(param2, 4);
|
||||
ASSERT(UTILS.Align(param2, 4));
|
||||
INC(param2, szWord);
|
||||
ASSERT(UTILS.Align(param2, szWord));
|
||||
pushc(param2);
|
||||
pushc(param1);
|
||||
CallRTL(IL._new, 3)
|
||||
@@ -1129,8 +1206,8 @@ BEGIN
|
||||
|IL.opTYPEGD:
|
||||
UnOp(r1);
|
||||
PushAll(0);
|
||||
subrc(r1, 4);
|
||||
ldr32(r1, r1);
|
||||
subrc(r1, szWord);
|
||||
ldr(r1, r1);
|
||||
push(r1);
|
||||
pushc(param2);
|
||||
CallRTL(IL._guardrec, 2);
|
||||
@@ -1145,7 +1222,11 @@ BEGIN
|
||||
jnz(ACC, param1)
|
||||
|
||||
|IL.opCONSTF:
|
||||
movrc(GetAnyReg(), UTILS.d2s(cmd.float))
|
||||
IF szWord = 8 THEN
|
||||
movrc(GetAnyReg(), UTILS.splitf(cmd.float, a, b))
|
||||
ELSE (* szWord = 4 *)
|
||||
movrc(GetAnyReg(), UTILS.d2s(cmd.float))
|
||||
END
|
||||
|
||||
|IL.opMULF:
|
||||
PushAll(2);
|
||||
@@ -1195,14 +1276,21 @@ BEGIN
|
||||
|
||||
|IL.opUMINF:
|
||||
UnOp(r1);
|
||||
Emit(opXORC, r1, ORD({31}))
|
||||
Emit(opRORC, r1, -1);
|
||||
Emit(opXORC, r1, 1);
|
||||
Emit(opRORC, r1, 1)
|
||||
|
||||
|IL.opFABS:
|
||||
UnOp(r1);
|
||||
Emit(opANDC, r1, ORD({0..30}))
|
||||
Emit(opLSLC, r1, 1);
|
||||
Emit(opLSRC, r1, 1)
|
||||
|
||||
|IL.opINF:
|
||||
movrc(GetAnyReg(), inf)
|
||||
r1 := GetAnyReg();
|
||||
Emit(opMOVC, r1, 1);
|
||||
Emit(opRORC, r1, 1);
|
||||
Emit(opASRC, r1, 7 + 3 * ORD(szWord = 8));
|
||||
Emit(opLSRC, r1, 1)
|
||||
|
||||
|IL.opPUSHF:
|
||||
UnOp(r1);
|
||||
@@ -1227,14 +1315,14 @@ BEGIN
|
||||
|
||||
|IL.opLADR_SAVE:
|
||||
UnOp(r1);
|
||||
Emit(opSTW, BP * 256 + r1, param2 * 4);
|
||||
Emit(opST, BP * 256 + r1, param2 * szWord);
|
||||
drop
|
||||
|
||||
|IL.opLADR_INCC:
|
||||
r1 := GetAnyReg();
|
||||
Emit(opLDW, BP * 256 + r1, param1 * 4);
|
||||
Emit(opLD, BP * 256 + r1, param1 * szWord);
|
||||
Emit(opADDC, r1, param2);
|
||||
Emit(opSTW, BP * 256 + r1, param1 * 4);
|
||||
Emit(opST, BP * 256 + r1, param1 * szWord);
|
||||
drop
|
||||
|
||||
END;
|
||||
@@ -1259,9 +1347,10 @@ BEGIN
|
||||
END prolog;
|
||||
|
||||
|
||||
PROCEDURE epilog (ram: INTEGER);
|
||||
PROCEDURE epilog (ram, szWord: INTEGER);
|
||||
VAR
|
||||
tcount, dcount, i, offTypes, offStrings, szData, szGlobal, szHeapStack: INTEGER;
|
||||
tcount, dcount, i, offTypes, offStrings,
|
||||
szData, szGlobal, szHeapStack: INTEGER;
|
||||
|
||||
BEGIN
|
||||
Emit(opSTOP, 0, 0);
|
||||
@@ -1279,8 +1368,8 @@ BEGIN
|
||||
OutByte(CHL.GetByte(IL.codes.data, i))
|
||||
END;
|
||||
|
||||
IF dcount MOD 4 # 0 THEN
|
||||
i := 4 - dcount MOD 4;
|
||||
IF dcount MOD szWord # 0 THEN
|
||||
i := szWord - dcount MOD szWord;
|
||||
WHILE i > 0 DO
|
||||
OutByte(0);
|
||||
DEC(i)
|
||||
@@ -1288,13 +1377,13 @@ BEGIN
|
||||
END;
|
||||
|
||||
szData := count - offTypes;
|
||||
szGlobal := (IL.codes.bss DIV 4 + 1) * 4;
|
||||
szGlobal := (IL.codes.bss DIV szWord + 1) * szWord;
|
||||
szHeapStack := ram - szData - szGlobal;
|
||||
|
||||
OutInt(offTypes);
|
||||
OutInt(offStrings);
|
||||
OutInt(szGlobal DIV 4);
|
||||
OutInt(szHeapStack DIV 4);
|
||||
OutInt(szGlobal DIV szWord);
|
||||
OutInt(szHeapStack DIV szWord);
|
||||
FOR i := 1 TO 8 DO
|
||||
OutInt(0)
|
||||
END
|
||||
@@ -1310,7 +1399,15 @@ VAR
|
||||
szData, szRAM: INTEGER;
|
||||
|
||||
BEGIN
|
||||
szData := (CHL.Length(IL.codes.types) + CHL.Length(IL.codes.data) DIV 4 + IL.codes.bss DIV 4 + 2) * 4;
|
||||
szWord := TARGETS.WordSize;
|
||||
IF szWord = 8 THEN
|
||||
ldr := ldr64;
|
||||
str := str64
|
||||
ELSE
|
||||
ldr := ldr32;
|
||||
str := str32
|
||||
END;
|
||||
szData := (CHL.Length(IL.codes.types) + CHL.Length(IL.codes.data) DIV szWord + IL.codes.bss DIV szWord + 2) * szWord;
|
||||
szRAM := MIN(MAX(options.ram, minRAM), maxRAM) * 1024;
|
||||
|
||||
IF szRAM - szData < 1024*1024 THEN
|
||||
@@ -1323,11 +1420,11 @@ BEGIN
|
||||
REG.Init(R, push, pop, mov, xchg, NIL, NIL, GPRs, {});
|
||||
|
||||
prolog;
|
||||
translate;
|
||||
epilog(szRAM);
|
||||
translate(szWord);
|
||||
epilog(szRAM, szWord);
|
||||
|
||||
WR.Close
|
||||
END CodeGen;
|
||||
|
||||
|
||||
END RVM32I.
|
||||
END RVMxI.
|
||||
@@ -9,7 +9,7 @@ MODULE STATEMENTS;
|
||||
|
||||
IMPORT
|
||||
|
||||
PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430, THUMB, RVM32I,
|
||||
PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430, THUMB, RVMxI,
|
||||
ERRORS, UTILS, AVL := AVLTREES, CONSOLE, C := COLLECTIONS, TARGETS;
|
||||
|
||||
|
||||
@@ -3310,7 +3310,7 @@ BEGIN
|
||||
getproc(rtl, "_isrec", IL._isrec);
|
||||
getproc(rtl, "_dllentry", IL._dllentry);
|
||||
getproc(rtl, "_sofinit", IL._sofinit)
|
||||
ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I} THEN
|
||||
ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
|
||||
getproc(rtl, "_fmul", IL._fmul);
|
||||
getproc(rtl, "_fdiv", IL._fdiv);
|
||||
getproc(rtl, "_fdivi", IL._fdivi);
|
||||
@@ -3322,7 +3322,7 @@ BEGIN
|
||||
getproc(rtl, "_flt", IL._flt);
|
||||
getproc(rtl, "_pack", IL._pack);
|
||||
getproc(rtl, "_unpk", IL._unpk);
|
||||
IF CPU = TARGETS.cpuRVM32I THEN
|
||||
IF CPU IN {TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
|
||||
getproc(rtl, "_error", IL._error)
|
||||
END
|
||||
END
|
||||
@@ -3401,7 +3401,8 @@ BEGIN
|
||||
|TARGETS.cpuX86: X86.CodeGen(outname, target, options)
|
||||
|TARGETS.cpuMSP430: MSP430.CodeGen(outname, target, options)
|
||||
|TARGETS.cpuTHUMB: THUMB.CodeGen(outname, target, options)
|
||||
|TARGETS.cpuRVM32I: RVM32I.CodeGen(outname, target, options)
|
||||
|TARGETS.cpuRVM32I,
|
||||
TARGETS.cpuRVM64I: RVMxI.CodeGen(outname, target, options)
|
||||
END
|
||||
|
||||
END compile;
|
||||
|
||||
+13
-5
@@ -7,6 +7,8 @@
|
||||
|
||||
MODULE TARGETS;
|
||||
|
||||
IMPORT UTILS;
|
||||
|
||||
|
||||
CONST
|
||||
|
||||
@@ -25,17 +27,21 @@ CONST
|
||||
Linux64SO* = 12;
|
||||
STM32CM3* = 13;
|
||||
RVM32I* = 14;
|
||||
RVM64I* = 15;
|
||||
|
||||
cpuX86* = 0; cpuAMD64* = 1; cpuMSP430* = 2; cpuTHUMB* = 3;
|
||||
cpuRVM32I* = 4;
|
||||
cpuRVM32I* = 4; cpuRVM64I* = 5;
|
||||
|
||||
osNONE* = 0; osWIN32* = 1; osWIN64* = 2;
|
||||
osLINUX32* = 3; osLINUX64* = 4; osKOS* = 5;
|
||||
|
||||
noDISPOSE = {MSP430, STM32CM3, RVM32I};
|
||||
noDISPOSE = {MSP430, STM32CM3, RVM32I, RVM64I};
|
||||
|
||||
noRTL = {MSP430};
|
||||
|
||||
libRVM32I = "RVMxI" + UTILS.slash + "32";
|
||||
libRVM64I = "RVMxI" + UTILS.slash + "64";
|
||||
|
||||
|
||||
TYPE
|
||||
|
||||
@@ -51,9 +57,9 @@ TYPE
|
||||
|
||||
VAR
|
||||
|
||||
Targets*: ARRAY 15 OF TARGET;
|
||||
Targets*: ARRAY 16 OF TARGET;
|
||||
|
||||
CPUs: ARRAY 5 OF
|
||||
CPUs: ARRAY 6 OF
|
||||
RECORD
|
||||
BitDepth, InstrSize: INTEGER;
|
||||
LittleEndian: BOOLEAN
|
||||
@@ -126,6 +132,7 @@ BEGIN
|
||||
EnterCPU(cpuMSP430, 16, 2, TRUE);
|
||||
EnterCPU(cpuTHUMB, 32, 2, TRUE);
|
||||
EnterCPU(cpuRVM32I, 32, 4, TRUE);
|
||||
EnterCPU(cpuRVM64I, 64, 8, TRUE);
|
||||
|
||||
Enter( MSP430, cpuMSP430, 0, osNONE, "msp430", "MSP430", ".hex");
|
||||
Enter( Win32C, cpuX86, 8, osWIN32, "win32con", "Windows", ".exe");
|
||||
@@ -141,5 +148,6 @@ BEGIN
|
||||
Enter( Linux64, cpuAMD64, 8, osLINUX64, "linux64exe", "Linux", "");
|
||||
Enter( Linux64SO, cpuAMD64, 8, osLINUX64, "linux64so", "Linux", ".so");
|
||||
Enter( STM32CM3, cpuTHUMB, 4, osNONE, "stm32cm3", "STM32CM3", ".hex");
|
||||
Enter( RVM32I, cpuRVM32I, 4, osNONE, "rvm32i", "RVM32I", ".bin");
|
||||
Enter( RVM32I, cpuRVM32I, 4, osNONE, "rvm32i", libRVM32I, ".bin");
|
||||
Enter( RVM64I, cpuRVM64I, 8, osNONE, "rvm64i", libRVM64I, ".bin");
|
||||
END TARGETS.
|
||||
+2
-2
@@ -23,8 +23,8 @@ CONST
|
||||
max32* = 2147483647;
|
||||
|
||||
vMajor* = 1;
|
||||
vMinor* = 51;
|
||||
Date* = "2021-02-09";
|
||||
vMinor* = 52;
|
||||
Date* = "2021-02-12";
|
||||
|
||||
FILE_EXT* = ".ob07";
|
||||
RTL_NAME* = "RTL";
|
||||
|
||||
@@ -6,34 +6,37 @@
|
||||
*)
|
||||
|
||||
(*
|
||||
RVM32I executor and disassembler
|
||||
RVMxI executor and disassembler
|
||||
|
||||
for win32 only
|
||||
for Windows only
|
||||
|
||||
Usage:
|
||||
RVM32I.exe <program file> -run [program parameters]
|
||||
RVM32I.exe <program file> -dis <output file>
|
||||
RVMxI.exe <program file> -run [program parameters]
|
||||
RVMxI.exe <program file> -dis <output file>
|
||||
*)
|
||||
|
||||
MODULE RVM32I;
|
||||
MODULE RVMxI;
|
||||
|
||||
IMPORT SYSTEM, File, Args, Out, API, HOST;
|
||||
|
||||
|
||||
CONST
|
||||
|
||||
szWORD = HOST.bit_depth DIV 8;
|
||||
|
||||
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opNOP = 5;
|
||||
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
|
||||
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15; (* 16, 17, 18 *)
|
||||
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15;
|
||||
opLDD = 16; (* 17, 18 *)
|
||||
opJMP = 19; opCALL = 20; opCALLI = 21;
|
||||
|
||||
opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
|
||||
opSTB = 34; opSTH = 36; opSTW = 38; (* 40, 42, 44 *)
|
||||
opSTB = 34; opSTH = 36; opSTW = 38; opSTD = 40; (* 42, 44 *)
|
||||
opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
|
||||
opLSL = 56; opROR = 58; (* 60, 62 *) opCMP = 64;
|
||||
|
||||
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
|
||||
opSTBC = 35; opSTHC = 37; opSTWC = 39; (* 41, 43, 45 *)
|
||||
opSTBC = 35; opSTHC = 37; opSTWC = 39; opSTDC = 41; (* 43, 45 *)
|
||||
opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
|
||||
opLSLC = 57; opRORC = 59; (* 61, 63 *) opCMPC = 65;
|
||||
|
||||
@@ -43,7 +46,7 @@ CONST
|
||||
opSEQ = 76; opSNE = 77; opSLT = 78; opSGE = 79; opSGT = 80; opSLE = 81;
|
||||
|
||||
|
||||
nREG = 8;
|
||||
nREG = 16;
|
||||
ACC = 0; BP = 3; SP = 4;
|
||||
|
||||
Types = 0;
|
||||
@@ -80,40 +83,110 @@ VAR
|
||||
|
||||
PROCEDURE syscall (ptr: INTEGER);
|
||||
VAR
|
||||
fn, p1, p2, p3, p4, r: INTEGER;
|
||||
fn, r: INTEGER;
|
||||
|
||||
proc2: PROCEDURE (a, b: INTEGER): INTEGER;
|
||||
proc3: PROCEDURE (a, b, c: INTEGER): INTEGER;
|
||||
proc4: PROCEDURE (a, b, c, d: INTEGER): INTEGER;
|
||||
|
||||
r1, r2: REAL;
|
||||
|
||||
|
||||
PROCEDURE GetInt (ptr, n: INTEGER): INTEGER;
|
||||
BEGIN
|
||||
SYSTEM.GET(ptr + SYSTEM.SIZE(INTEGER) * n, n)
|
||||
RETURN n
|
||||
END GetInt;
|
||||
|
||||
|
||||
PROCEDURE GetReal (ptr, n: INTEGER): REAL;
|
||||
VAR
|
||||
r: REAL;
|
||||
|
||||
BEGIN
|
||||
SYSTEM.GET(ptr + SYSTEM.SIZE(INTEGER) * n, r)
|
||||
RETURN r
|
||||
END GetReal;
|
||||
|
||||
|
||||
BEGIN
|
||||
SYSTEM.GET(ptr, fn);
|
||||
SYSTEM.GET(ptr + 4, p1);
|
||||
SYSTEM.GET(ptr + 8, p2);
|
||||
SYSTEM.GET(ptr + 12, p3);
|
||||
SYSTEM.GET(ptr + 16, p4);
|
||||
fn := GetInt(ptr, 0);
|
||||
CASE fn OF
|
||||
| 0: HOST.ExitProcess(p1)
|
||||
| 1: SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.GetCurrentDirectory));
|
||||
r := proc2(p1, p2)
|
||||
| 2: SYSTEM.PUT(SYSTEM.ADR(proc3), SYSTEM.ADR(HOST.GetArg));
|
||||
r := proc3(p1 + 2, p2, p3)
|
||||
| 3: SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileRead));
|
||||
SYSTEM.PUT(ptr, proc4(p1, p2, p3, p4))
|
||||
| 4: SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileWrite));
|
||||
SYSTEM.PUT(ptr, proc4(p1, p2, p3, p4))
|
||||
| 5: SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileCreate));
|
||||
SYSTEM.PUT(ptr, proc2(p1, p2))
|
||||
| 6: HOST.FileClose(p1)
|
||||
| 7: SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileOpen));
|
||||
SYSTEM.PUT(ptr, proc2(p1, p2))
|
||||
| 8: HOST.OutChar(CHR(p1))
|
||||
| 9: SYSTEM.PUT(ptr, HOST.GetTickCount())
|
||||
|10: SYSTEM.PUT(ptr, HOST.UnixTime())
|
||||
|11: SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.isRelative));
|
||||
SYSTEM.PUT(ptr, proc2(p1, p2))
|
||||
|12: SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.chmod));
|
||||
r := proc2(p1, p2)
|
||||
| 0:
|
||||
HOST.ExitProcess(GetInt(ptr, 1))
|
||||
|
||||
| 1:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.GetCurrentDirectory));
|
||||
r := proc2(GetInt(ptr, 1), GetInt(ptr, 2))
|
||||
|
||||
| 2:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc3), SYSTEM.ADR(HOST.GetArg));
|
||||
r := proc3(GetInt(ptr, 1) + 2, GetInt(ptr, 2), GetInt(ptr, 3))
|
||||
|
||||
| 3:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileRead));
|
||||
SYSTEM.PUT(ptr, proc4(GetInt(ptr, 1), GetInt(ptr, 2), GetInt(ptr, 3), GetInt(ptr, 4)))
|
||||
|
||||
| 4:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileWrite));
|
||||
SYSTEM.PUT(ptr, proc4(GetInt(ptr, 1), GetInt(ptr, 2), GetInt(ptr, 3), GetInt(ptr, 4)))
|
||||
|
||||
| 5:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileCreate));
|
||||
SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
|
||||
|
||||
| 6:
|
||||
HOST.FileClose(GetInt(ptr, 1))
|
||||
|
||||
| 7:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileOpen));
|
||||
SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
|
||||
|
||||
| 8:
|
||||
HOST.OutChar(CHR(GetInt(ptr, 1)))
|
||||
|
||||
| 9:
|
||||
SYSTEM.PUT(ptr, HOST.GetTickCount())
|
||||
|
||||
|10:
|
||||
SYSTEM.PUT(ptr, HOST.UnixTime())
|
||||
|
||||
|11:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.isRelative));
|
||||
SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
|
||||
|
||||
|12:
|
||||
SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.chmod));
|
||||
r := proc2(GetInt(ptr, 1), GetInt(ptr, 2))
|
||||
|
||||
|100..103:
|
||||
r1 := GetReal(ptr, 1);
|
||||
r2 := GetReal(ptr, 2);
|
||||
CASE fn OF
|
||||
|100: SYSTEM.PUT(ptr, r2 * r1)
|
||||
|101: SYSTEM.PUT(ptr, r2 / r1)
|
||||
|102: SYSTEM.PUT(ptr, r2 + r1)
|
||||
|103: SYSTEM.PUT(ptr, r2 - r1)
|
||||
END
|
||||
|
||||
|104:
|
||||
r1 := GetReal(ptr, 2);
|
||||
r2 := GetReal(ptr, 3);
|
||||
CASE GetInt(ptr, 1) OF
|
||||
|0: SYSTEM.PUT(ptr, ORD(r2 = r1))
|
||||
|1: SYSTEM.PUT(ptr, ORD(r2 # r1))
|
||||
|2: SYSTEM.PUT(ptr, ORD(r2 < r1))
|
||||
|3: SYSTEM.PUT(ptr, ORD(r2 <= r1))
|
||||
|4: SYSTEM.PUT(ptr, ORD(r2 > r1))
|
||||
|5: SYSTEM.PUT(ptr, ORD(r2 >= r1))
|
||||
END
|
||||
|
||||
|105:
|
||||
SYSTEM.PUT(ptr, FLOOR(GetReal(ptr, 1)))
|
||||
|
||||
|106:
|
||||
SYSTEM.PUT(ptr, FLT(GetInt(ptr, 1)))
|
||||
|
||||
END
|
||||
END syscall;
|
||||
|
||||
@@ -156,24 +229,30 @@ BEGIN
|
||||
WHILE cmd # NIL DO
|
||||
param1 := cmd.param1;
|
||||
param2 := cmd.param2;
|
||||
|
||||
CASE cmd.op OF
|
||||
|opSTOP: cmd := last
|
||||
|opRET: SYSTEM.GET(R[SP], cmd); INC(R[SP], 4)
|
||||
|opENTER: DEC(R[SP], 4); SYSTEM.PUT32(R[SP], R[BP]); R[BP] := R[SP]; WHILE param1 > 0 DO DEC(R[SP], 4); SYSTEM.PUT32(R[SP], 0); DEC(param1) END
|
||||
|opPOP: SYSTEM.GET32(R[SP], R[param1]); INC(R[SP], 4)
|
||||
|opRET: SYSTEM.GET(R[SP], cmd); INC(R[SP], szWORD)
|
||||
|opENTER: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], R[BP]); R[BP] := R[SP];
|
||||
WHILE param1 > 0 DO DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], 0); DEC(param1) END
|
||||
|opPOP: SYSTEM.GET(R[SP], R[param1]); INC(R[SP], szWORD)
|
||||
|opPUSH: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], R[param1])
|
||||
|opPUSHC: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], param1)
|
||||
|opCALL: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], cmd); cmd := Labels[param1]
|
||||
|opCALLI: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], cmd); SYSTEM.GET(SYSTEM.ADR(R[param1]), cmd)
|
||||
|opNEG: R[param1] := -R[param1]
|
||||
|opNOT: R[param1] := ORD(-BITS(R[param1]))
|
||||
|opNOP:
|
||||
|opXCHG: i := R[param1]; R[param1] := R[param2]; R[param2] := i
|
||||
|opLDB: i := param1 MOD 256; SYSTEM.GET8(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 256
|
||||
|opLDH: i := param1 MOD 256; SYSTEM.GET16(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 65536
|
||||
|opLDW: SYSTEM.GET32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opPUSH: DEC(R[SP], 4); SYSTEM.PUT32(R[SP], R[param1])
|
||||
|opPUSHC: DEC(R[SP], 4); SYSTEM.PUT32(R[SP], param1)
|
||||
|opLLA: SYSTEM.GET32(SYSTEM.ADR(Labels[param2]), R[param1])
|
||||
|opLDW: SYSTEM.GET32(R[param1 DIV 256] + param2, R[param1 MOD 256]);
|
||||
$IF (CPU_X8664)
|
||||
R[param1 MOD 256] := R[param1 MOD 256] MOD 100000000H
|
||||
$END
|
||||
|opLDD: SYSTEM.GET(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opLLA: SYSTEM.GET(SYSTEM.ADR(Labels[param2]), R[param1])
|
||||
|opJMP: cmd := Labels[param1]
|
||||
|opCALL: DEC(R[SP], 4); SYSTEM.PUT(R[SP], cmd); cmd := Labels[param1]
|
||||
|opCALLI: DEC(R[SP], 4); SYSTEM.PUT(R[SP], cmd); SYSTEM.GET(SYSTEM.ADR(R[param1]), cmd)
|
||||
|opMOV: R[param1] := R[param2]
|
||||
|opMOVC: R[param1] := param2
|
||||
|opMUL: R[param1] := R[param1] * R[param2]
|
||||
@@ -189,9 +268,11 @@ BEGIN
|
||||
|opSTB: SYSTEM.PUT8(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opSTH: SYSTEM.PUT16(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opSTW: SYSTEM.PUT32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opSTD: SYSTEM.PUT(R[param1 DIV 256] + param2, R[param1 MOD 256])
|
||||
|opSTBC: SYSTEM.PUT8(R[param1], param2)
|
||||
|opSTHC: SYSTEM.PUT16(R[param1], param2)
|
||||
|opSTWC: SYSTEM.PUT32(R[param1], param2)
|
||||
|opSTDC: SYSTEM.PUT(R[param1], param2)
|
||||
|opAND: R[param1] := ORD(BITS(R[param1]) * BITS(R[param2]))
|
||||
|opANDC: R[param1] := ORD(BITS(R[param1]) * BITS(param2))
|
||||
|opOR: R[param1] := ORD(BITS(R[param1]) + BITS(R[param2]))
|
||||
@@ -275,12 +356,12 @@ VAR
|
||||
|
||||
PROCEDURE Hex (x: INTEGER);
|
||||
VAR
|
||||
str: ARRAY 11 OF CHAR;
|
||||
str: ARRAY 19 OF CHAR;
|
||||
n: INTEGER;
|
||||
|
||||
BEGIN
|
||||
n := 10;
|
||||
str[10] := 0X;
|
||||
n := szWORD * 2 + 2;
|
||||
str[n] := 0X;
|
||||
WHILE n > 2 DO
|
||||
str[n - 1] := hexdgt(x MOD 16);
|
||||
x := x DIV 16;
|
||||
@@ -372,6 +453,7 @@ BEGIN
|
||||
|opLDB: String("LDB "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|
||||
|opLDH: String("LDH "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|
||||
|opLDW: String("LDW "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|
||||
|opLDD: String("LDD "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|
||||
|opPUSH: String("PUSH "); Reg(param1)
|
||||
|opPUSHC: String("PUSH "); Hex(param1)
|
||||
|opLLA: String("LLA "); RegL(param1, param2)
|
||||
@@ -393,9 +475,11 @@ BEGIN
|
||||
|opSTB: String("STB ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|
||||
|opSTH: String("STH ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|
||||
|opSTW: String("STW ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|
||||
|opSTD: String("STD ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|
||||
|opSTBC: String("STB ["); Reg(param1); String("], "); Hex(param2)
|
||||
|opSTHC: String("STH ["); Reg(param1); String("], "); Hex(param2)
|
||||
|opSTWC: String("STW ["); Reg(param1); String("], "); Hex(param2)
|
||||
|opSTDC: String("STD ["); Reg(param1); String("], "); Hex(param2)
|
||||
|opAND: String("AND "); Reg2(param1, param2)
|
||||
|opANDC: String("AND "); RegC(param1, param2)
|
||||
|opOR: String("OR "); Reg2(param1, param2)
|
||||
@@ -443,7 +527,7 @@ BEGIN
|
||||
ELSE
|
||||
String(", ")
|
||||
END;
|
||||
SYSTEM.GET32(ptr, t); INC(ptr, 4);
|
||||
SYSTEM.GET(ptr, t); INC(ptr, szWORD);
|
||||
Hex(t)
|
||||
END;
|
||||
Ln;
|
||||
@@ -480,9 +564,9 @@ VAR
|
||||
|
||||
BEGIN
|
||||
op := 0; param1 := 0; param2 := 0;
|
||||
SYSTEM.GET32(adr, op);
|
||||
SYSTEM.GET32(adr + 4, param1);
|
||||
SYSTEM.GET32(adr + 8, param2);
|
||||
SYSTEM.GET(adr, op);
|
||||
SYSTEM.GET(adr + szWORD, param1);
|
||||
SYSTEM.GET(adr + szWORD * 2, param2);
|
||||
NEW(res);
|
||||
res.op := op;
|
||||
res.param1 := param1;
|
||||
@@ -521,11 +605,11 @@ BEGIN
|
||||
offTypes := descr[0];
|
||||
ASSERT(offTypes < fsize - DescrSize);
|
||||
ASSERT(offTypes > 0);
|
||||
ASSERT(offTypes MOD 12 = 0);
|
||||
ASSERT(offTypes MOD (3 * szWORD) = 0);
|
||||
offStrings := descr[1];
|
||||
ASSERT(offStrings < fsize - DescrSize);
|
||||
ASSERT(offStrings > 0);
|
||||
ASSERT(offStrings MOD 4 = 0);
|
||||
ASSERT(offStrings MOD szWORD = 0);
|
||||
ASSERT(offStrings > offTypes);
|
||||
GlobalSize := descr[2];
|
||||
ASSERT(GlobalSize > 0);
|
||||
@@ -540,21 +624,22 @@ BEGIN
|
||||
ASSERT(Sections[Strings] # 0);
|
||||
SYSTEM.MOVE(file + offStrings, Sections[Strings], fsize - offStrings - DescrSize);
|
||||
|
||||
Sections[Global] := API._NEW(GlobalSize * 4);
|
||||
Sections[Global] := API._NEW(GlobalSize * szWORD);
|
||||
ASSERT(Sections[Global] # 0);
|
||||
|
||||
Sections[Heap] := API._NEW(HeapStackSize * 4);
|
||||
Sections[Heap] := API._NEW(HeapStackSize * szWORD);
|
||||
ASSERT(Sections[Heap] # 0);
|
||||
|
||||
Sections[Stack] := Sections[Heap] + HeapStackSize * 4 - 32;
|
||||
Sections[Stack] := Sections[Heap] + HeapStackSize * szWORD - szWORD*8;
|
||||
|
||||
n := offTypes DIV 12;
|
||||
first := GetCommand(file + offTypes - n * 12);
|
||||
n := offTypes DIV (3 * szWORD);
|
||||
|
||||
first := GetCommand(file + offTypes - n * (3 * szWORD));
|
||||
first.prev := NIL;
|
||||
last := first;
|
||||
DEC(n);
|
||||
WHILE n > 0 DO
|
||||
cmd := GetCommand(file + offTypes - n * 12);
|
||||
cmd := GetCommand(file + offTypes - n * (3 * szWORD));
|
||||
IF cmd.op = opLABEL THEN
|
||||
Labels[cmd.param1] := cmd
|
||||
END;
|
||||
@@ -568,7 +653,7 @@ BEGIN
|
||||
IF param = "-dis" THEN
|
||||
Args.GetArg(3, name);
|
||||
IF name # "" THEN
|
||||
disasm(name, (offStrings - offTypes) DIV 4, fsize - offStrings - DescrSize, GlobalSize, HeapStackSize)
|
||||
disasm(name, (offStrings - offTypes) DIV szWORD, fsize - offStrings - DescrSize, GlobalSize, HeapStackSize)
|
||||
END
|
||||
ELSIF param = "-run" THEN
|
||||
exec(Labels, first, last, Sections)
|
||||
@@ -580,6 +665,5 @@ END main;
|
||||
|
||||
|
||||
BEGIN
|
||||
ASSERT(API.BIT_DEPTH = 32);
|
||||
main
|
||||
END RVM32I.
|
||||
END RVMxI.
|
||||
@@ -1,18 +1,20 @@
|
||||
|
||||
Экспериментальная 32-битная виртуальная машина RVM32I
|
||||
Экспериментальная 32/64-битная виртуальная машина RVMxI
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
Использование
|
||||
|
||||
Скомпилировать исполнитель/дизассемблер в \tools\RVM32I.ob07 (для Windows32 Console):
|
||||
Скомпилировать исполнитель/дизассемблер в \tools\RVMxI.ob07 (для Windows32/64 Console):
|
||||
|
||||
Compiler.exe .\tools\RVM32I.ob07 win32con -nochk a
|
||||
Compiler.exe .\tools\RVMxI.ob07 win32con -nochk a -out RVM32I.exe
|
||||
Compiler.exe .\tools\RVMxI.ob07 win64con -nochk a -out RVM64I.exe
|
||||
|
||||
Будет создан файл "\tools\RVM32I.exe".
|
||||
Будет создан файл "RVM32I.exe" и/или "RVM64I.exe".
|
||||
|
||||
Компилировать программу в байт-код RVM32I:
|
||||
Компилировать программу в байт-код RVMxI:
|
||||
|
||||
Compiler.exe program.ob07 rvm32i [-ram size]
|
||||
Compiler.exe program.ob07 rvm64i [-ram size]
|
||||
-ram size -- установить размер оперативной памяти для программы в килобайтах 32768..262144
|
||||
(32..256 Мбайт), по умолчанию 32768 (32 Мбайт)
|
||||
|
||||
@@ -21,19 +23,21 @@
|
||||
Выпонить программу:
|
||||
|
||||
RVM32I.exe program.bin -run
|
||||
RVM64I.exe program.bin -run
|
||||
|
||||
Дизассемблировать программу:
|
||||
|
||||
RVM32I.exe program.bin -dis program.asm
|
||||
RVM32I.exe program.bin -dis program.txt
|
||||
RVM64I.exe program.bin -dis program.txt
|
||||
|
||||
Будет создан файл "program.asm".
|
||||
Будет создан файл "program.txt".
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
Архитектура
|
||||
|
||||
Регистры
|
||||
|
||||
Не меньше пяти 32-битных регистров:
|
||||
Не меньше пяти 32/64-битных регистров:
|
||||
|
||||
R0, R1, R2 регистры общего назначения
|
||||
BP(R3) указатель кадра стэка
|
||||
@@ -44,7 +48,8 @@
|
||||
Регистра связи нет (адрес возврата передается через стэк),
|
||||
регистр-счетчик команд (PC) -- скрытый, регистр флагов -- скрытый.
|
||||
|
||||
Нет вещественных регистров, операции с плавающей точкой (single) эмулируются.
|
||||
Нет вещественных регистров, операции с плавающей точкой (single (32-бит) или double (64-бит))
|
||||
эмулируются.
|
||||
|
||||
Формат кадра стэка
|
||||
|
||||
@@ -52,10 +57,16 @@
|
||||
|
||||
меньше <- |лок. переменные|старый BP|адрес возврата|парам1|парам2|...|парамN| -> больше
|
||||
|
||||
(* 32 бита *)
|
||||
адрес(парам1) = BP + 8
|
||||
адрес(парам2) = BP + 12
|
||||
...
|
||||
|
||||
(* 64 бита *)
|
||||
адрес(парам1) = BP + 16
|
||||
адрес(парам2) = BP + 24
|
||||
...
|
||||
|
||||
Параметры передаются через стэк справа налево (как cdecl), результат передается через R0,
|
||||
вызывающая процедура очищает стэк (как cdecl).
|
||||
|
||||
@@ -78,10 +89,10 @@
|
||||
|
||||
Где:
|
||||
|
||||
INTEGER = INT32
|
||||
i = offTypes DIV 12;
|
||||
t = (offStrings - offTypes) DIV 4
|
||||
s = FILE_SIZE - offStrings - 48
|
||||
INTEGER = INT32/INT64
|
||||
i = offTypes DIV (3 * sizeof(INTEGER));
|
||||
t = (offStrings - offTypes) DIV sizeof(INTEGER)
|
||||
s = FILE_SIZE - offStrings - 12 * sizeof(INTEGER)
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
Система команд
|
||||
@@ -97,10 +108,13 @@
|
||||
XCHG Rn, Rm 6 n m temp := Rn; Rn := Rm; Rm := temp
|
||||
LDB Rn, [Rm + imm] 7 m*256 + n imm Rn := UInt8Ptr(Rm + imm)^
|
||||
LDH Rn, [Rm + imm] 8 m*256 + n imm Rn := UInt16Ptr(Rm + imm)^
|
||||
LDW Rn, [Rm + imm] 9 m*256 + n imm Rn := Int32Ptr(Rm + imm)^
|
||||
PUSH Rn 10 n 0 DEC(SP, 4); Int32Ptr(SP)^ := Rn
|
||||
PUSH imm 11 imm 0 DEC(SP, 4); Int32Ptr(SP)^ := imm
|
||||
POP Rn 12 n 0 Rn := Int32Ptr(SP)^; INC(SP, 4)
|
||||
LDW Rn, [Rm + imm] 9 m*256 + n imm Rn := UInt32Ptr(Rm + imm)^
|
||||
* PUSH Rn 10 n 0 DEC(SP, 4); UInt32Ptr(SP)^ := Rn
|
||||
* PUSH imm 11 imm 0 DEC(SP, 4); UInt32Ptr(SP)^ := imm
|
||||
* POP Rn 12 n 0 Rn := UInt32Ptr(SP)^; INC(SP, 4)
|
||||
** PUSH Rn 10 n 0 DEC(SP, 8); UInt64Ptr(SP)^ := Rn
|
||||
** PUSH imm 11 imm 0 DEC(SP, 8); UInt64Ptr(SP)^ := imm
|
||||
** POP Rn 12 n 0 Rn := UInt64Ptr(SP)^; INC(SP, 8)
|
||||
L#hex: 13 hex 0 метка:
|
||||
LEA Rn, TYPES + imm 14 n + 000H imm Rn := imm + address(TYPES)
|
||||
LEA Rn, STRINGS + imm 14 n + 100H imm Rn := imm + address(STRINGS)
|
||||
@@ -108,6 +122,7 @@
|
||||
LEA Rn, HEAP + imm 14 n + 300H imm Rn := imm + address(HEAP)
|
||||
LEA Rn, STACK + imm 14 n + 400H imm Rn := imm + address(STACK)
|
||||
LLA Rn, L#hex 15 n hex Rn := address(L#hex)
|
||||
** LDD Rn, [Rm + imm] 16 m*256 + n imm Rn := UInt64Ptr(Rm + imm)^
|
||||
|
||||
JMP L#hex 19 hex 0 goto L#hex
|
||||
CALL L#hex 20 hex 0 push PC; goto L#hex
|
||||
@@ -128,8 +143,12 @@
|
||||
STB [Rn], imm 35 n imm UInt8Ptr(Rn)^ := imm MOD 256
|
||||
STH [Rn + imm], Rm 36 n*256 + m imm UInt16Ptr(Rn + imm)^ := Rm MOD 65536
|
||||
STH [Rn], imm 37 n imm UInt16Ptr(Rn)^ := imm MOD 65536
|
||||
STW [Rn + imm], Rm 38 n*256 + m imm Int32Ptr(Rn + imm)^ := Rm
|
||||
STW [Rn], imm 39 n imm Int32Ptr(Rn)^ := imm
|
||||
* STW [Rn + imm], Rm 38 n*256 + m imm UInt32Ptr(Rn + imm)^ := Rm
|
||||
* STW [Rn], imm 39 n imm UInt32Ptr(Rn)^ := imm
|
||||
** STW [Rn + imm], Rm 38 n*256 + m imm UInt32Ptr(Rn + imm)^ := Rm MOD 100000000H
|
||||
** STW [Rn], imm 39 n imm UInt32Ptr(Rn)^ := imm MOD 100000000H
|
||||
** STD [Rn + imm], Rm 40 n*256 + m imm UInt64Ptr(Rn + imm)^ := Rm
|
||||
** STD [Rn], imm 41 n imm UInt64Ptr(Rn)^ := imm
|
||||
|
||||
AND Rn, Rm 46 n m Rn := ORD(BITS(Rn) * BITS(Rm))
|
||||
AND Rn, imm 47 n imm Rn := ORD(BITS(Rn) * BITS(imm))
|
||||
@@ -169,6 +188,9 @@
|
||||
в командах перехода по условию (JEQ, JNE, JLT, JGE, JGT, JLE, JBT) а также в командах
|
||||
установки регистра по условию (SEQ, SNE, SLT, SGE, SGT, SLE).
|
||||
|
||||
* Команда для 32-битной виртуальной машины
|
||||
** Команда для 64-битной виртуальной машины
|
||||
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
Общая структура программы
|
||||
@@ -237,10 +259,10 @@
|
||||
BYTE 0x4C, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x00
|
||||
|
||||
GLOBAL:
|
||||
WORDS 0x00000004 (* размер глобальных переменных в словах (слово = 4 байта) *)
|
||||
WORDS 0x00000004 (* размер глобальных переменных в словах (слово = 4 или 8 байт) *)
|
||||
|
||||
HEAP:
|
||||
WORDS 0x007FFFBF (* размер области кучи/стэка в словах (слово = 4 байта) *)
|
||||
WORDS 0x007FFFBF (* размер области кучи/стэка в словах (слово = 4 или 8 байт) *)
|
||||
STACK:
|
||||
WORDS 8 (* зарезервировано *)
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Reference in new issue
Block a user