RVMxI: 32 и 64 бита

This commit is contained in:
AntKrotov committed 2021-02-12 00:02:44 +03:00
1 parent 049d48faa9
commit 6fb87a797f
22 files changed
+1438 -166

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+192
View File
@@ -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.
+288
View File
@@ -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.
+432
View File
@@ -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.
+133
View File
@@ -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.
+5
View File
@@ -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
+5
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+166 -69
View File
@@ -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.
+5 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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";
+147 -63
View File
@@ -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.
+43 -21
View File
@@ -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 (* зарезервировано *)
---------------------------------------------------------------------------------------------------