RVM32I: перестроение системы команд

This commit is contained in:
AntKrotov committed 2021-02-09 21:47:37 +03:00
1 parent 2d48266a69
commit 94e6484c8a
7 files changed
+141 -154

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -23,7 +23,7 @@ PROCEDURE [code] syscall* (ptr: INTEGER)
22, 0, SP, (* MOV R0, SP *)
27, 0, 4, (* ADD R0, 4 *)
9, 0, 0, (* LDW R0, R0 *)
80, 0, 0; (* SYSCALL R0 *)
67, 0, 0; (* SYSCALL R0 *)
PROCEDURE Char (c: CHAR);
+66 -82
View File
@@ -31,22 +31,23 @@ CONST
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opABS = 5;
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opJNA = 16; opJGA = 17;
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15; opJNA = 16; opJGA = 17;
opJLA = 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; opINCL = 40; opEXCL = 42;
opIN = 44; opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opEQ = 64; opNE = 66;
opLT = 68; opLE = 70; opGT = 72; opGE = 74; opBT = 76;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opCMP = 64;
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
opSTBC = 35; opSTHC = 37; opSTWC = 39; opINCLC = 41; opEXCLC = 43;
opINC = 45; opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opEQC = 65; opNEC = 67;
opLTC = 69; opLEC = 71; opGTC = 73; opGEC = 75; opBTC = 77;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opCMPC = 65;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opLLA = 82;
opSYSCALL = 67; opJBT = 68; opADDRC = 69;
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;
@@ -230,7 +231,8 @@ END ProcAdr;
PROCEDURE jnz (r, label: INTEGER);
BEGIN
Emit(opJNZ, r, label)
Emit(opCMPC, r, 0);
Emit(opJNE, label, 0)
END jnz;
@@ -241,6 +243,20 @@ BEGIN
END CallRTL;
PROCEDURE jcc (cc: INTEGER): INTEGER;
BEGIN
CASE cc OF
|IL.opEQ, IL.opEQC: cc := opJEQ
|IL.opNE, IL.opNEC: cc := opJNE
|IL.opLT, IL.opLTC: cc := opJLT
|IL.opLE, IL.opLEC: cc := opJLE
|IL.opGT, IL.opGTC: cc := opJGT
|IL.opGE, IL.opGEC: cc := opJGE
END
RETURN cc
END jcc;
PROCEDURE translate;
VAR
cmd, next: IL.COMMAND;
@@ -546,59 +562,27 @@ BEGIN
mov(r1, r2);
drop
|IL.opEQ:
|IL.opEQ .. IL.opGE, IL.opEQC .. IL.opGEC:
IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
BinOp(r1, r2);
Emit(opEQ, r1, r2);
Emit(opCMP, r1, r2);
drop
|IL.opNE:
BinOp(r1, r2);
Emit(opNE, r1, r2);
ELSE
UnOp(r1);
Emit(opCMPC, r1, param2)
END;
next := cmd.next(IL.COMMAND);
IF next.opcode = IL.opJZ THEN
Emit(ORD(BITS(jcc(opcode)) / {0}), next.param1, 0);
cmd := next;
drop
|IL.opLT:
BinOp(r1, r2);
Emit(opLT, r1, r2);
ELSIF next.opcode = IL.opJNZ THEN
Emit(jcc(opcode), next.param1, 0);
cmd := next;
drop
|IL.opLE:
BinOp(r1, r2);
Emit(opLE, r1, r2);
drop
|IL.opGT:
BinOp(r1, r2);
Emit(opGT, r1, r2);
drop
|IL.opGE:
BinOp(r1, r2);
Emit(opGE, r1, r2);
drop
|IL.opEQC:
UnOp(r1);
Emit(opEQC, r1, param2)
|IL.opNEC:
UnOp(r1);
Emit(opNEC, r1, param2)
|IL.opLTC:
UnOp(r1);
Emit(opLTC, r1, param2)
|IL.opLEC:
UnOp(r1);
Emit(opLEC, r1, param2)
|IL.opGTC:
UnOp(r1);
Emit(opGTC, r1, param2)
|IL.opGEC:
UnOp(r1);
Emit(opGEC, r1, param2)
ELSE
Emit(jcc(opcode) + 6, r1, 0)
END
|IL.opJNZ1:
UnOp(r1);
@@ -606,7 +590,8 @@ BEGIN
|IL.opJG:
UnOp(r1);
Emit(opJGZ, r1, param1)
Emit(opCMPC, r1, 0);
Emit(opJGT, param1, 0)
|IL.opJNZ:
UnOp(r1);
@@ -615,7 +600,8 @@ BEGIN
|IL.opJZ:
UnOp(r1);
Emit(opJZ, r1, param1);
Emit(opCMPC, r1, 0);
Emit(opJEQ, param1, 0);
drop
|IL.opMULS:
@@ -790,7 +776,8 @@ BEGIN
|IL.opSBOOL:
BinOp(r2, r1);
Emit(opNEC, r2, 0);
Emit(opCMPC, r2, 0);
Emit(opSNE, r2, 0);
str8(r1, r2);
drop;
drop
@@ -870,39 +857,33 @@ BEGIN
|IL.opEQB, IL.opNEB:
BinOp(r1, r2);
Emit(opNEC, r1, 0);
Emit(opNEC, r2, 0);
Emit(opCMPC, r1, 0);
Emit(opSNE, r1, 0);
Emit(opCMPC, r2, 0);
Emit(opSNE, r2, 0);
Emit(opCMP, r1, r2);
IF opcode = IL.opEQB THEN
Emit(opEQ, r1, r2)
Emit(opSEQ, r1, 0)
ELSE
Emit(opNE, r1, r2)
Emit(opSNE, r1, 0)
END;
drop
|IL.opCHKBYTE:
BinOp(r1, r2);
r3 := GetAnyReg();
mov(r3, r1);
Emit(opBTC, r3, 256);
jnz(r3, param1);
drop
Emit(opCMPC, r1, 256);
Emit(opJBT, param1, 0)
|IL.opCHKIDX:
UnOp(r1);
r2 := GetAnyReg();
mov(r2, r1);
Emit(opBTC, r2, param2);
jnz(r2, param1);
drop
Emit(opCMPC, r1, param2);
Emit(opJBT, param1, 0)
|IL.opCHKIDX2:
BinOp(r1, r2);
IF param2 # -1 THEN
r3 := GetAnyReg();
mov(r3, r2);
Emit(opBT, r3, r1);
jnz(r3, param1);
drop
Emit(opCMP, r2, r1);
Emit(opJBT, param1, 0)
END;
INCL(R.regs, r1);
DEC(R.top);
@@ -911,10 +892,11 @@ BEGIN
|IL.opEQP, IL.opNEP:
ProcAdr(GetAnyReg(), param1);
BinOp(r1, r2);
Emit(opCMP, r1, r2);
IF opcode = IL.opEQP THEN
Emit(opEQ, r1, r2)
Emit(opSEQ, r1, 0)
ELSE
Emit(opNE, r1, r2)
Emit(opSNE, r1, 0)
END;
drop
@@ -952,11 +934,13 @@ BEGIN
|IL.opNOT:
UnOp(r1);
Emit(opEQC, r1, 0)
Emit(opCMPC, r1, 0);
Emit(opSEQ, r1, 0)
|IL.opORD:
UnOp(r1);
Emit(opNEC, r1, 0)
Emit(opCMPC, r1, 0);
Emit(opSNE, r1, 0)
|IL.opMIN:
BinOp(r1, r2);
+2 -2
View File
@@ -23,8 +23,8 @@ CONST
max32* = 2147483647;
vMajor* = 1;
vMinor* = 50;
Date* = "2021-02-05";
vMinor* = 51;
Date* = "2021-02-09";
FILE_EXT* = ".ob07";
RTL_NAME* = "RTL";
+39 -40
View File
@@ -24,22 +24,23 @@ CONST
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opABS = 5;
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opJNA = 16; opJGA = 17;
opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15; opJNA = 16; opJGA = 17;
opJLA = 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; opINCL = 40; opEXCL = 42;
opIN = 44; opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opEQ = 64; opNE = 66;
opLT = 68; opLE = 70; opGT = 72; opGE = 74; opBT = 76;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opCMP = 64;
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
opSTBC = 35; opSTHC = 37; opSTWC = 39; opINCLC = 41; opEXCLC = 43;
opINC = 45; opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opEQC = 65; opNEC = 67;
opLTC = 69; opLEC = 71; opGTC = 73; opGEC = 75; opBTC = 77;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opCMPC = 65;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opLLA = 82;
opSYSCALL = 67; opJBT = 68; opADDRC = 69;
opJEQ = 70; opJNE = 71; opJLT = 72; opJGE = 73; opJGT = 74; opJLE = 75;
opSEQ = 76; opSNE = 77; opSLT = 78; opSGE = 79; opSGT = 80; opSLE = 81;
nREG = 8;
@@ -123,6 +124,8 @@ VAR
param1, param2, i: INTEGER;
R: ARRAY nREG OF INTEGER;
fe, fl, fb: BOOLEAN;
BEGIN
FOR i := 0 TO LEN(Labels) - 1 DO
cmd := Labels[i];
@@ -167,9 +170,6 @@ BEGIN
|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)
|opJGZ: IF R[param1] > 0 THEN cmd := Labels[param2] END
|opJZ: IF R[param1] = 0 THEN cmd := Labels[param2] END
|opJNZ: IF R[param1] # 0 THEN cmd := Labels[param2] END
|opLLA: SYSTEM.GET32(SYSTEM.ADR(Labels[param2]), R[param1])
|opJGA: IF R[ACC] > param1 THEN cmd := Labels[param2] END
|opJLA: IF R[ACC] < param1 THEN cmd := Labels[param2] END
@@ -219,24 +219,25 @@ BEGIN
|opMINC: R[param1] := MIN(R[param1], param2)
|opMAX: R[param1] := MAX(R[param1], R[param2])
|opMAXC: R[param1] := MAX(R[param1], param2)
|opEQ: R[param1] := ORD(R[param1] = R[param2])
|opEQC: R[param1] := ORD(R[param1] = param2)
|opNE: R[param1] := ORD(R[param1] # R[param2])
|opNEC: R[param1] := ORD(R[param1] # param2)
|opLT: R[param1] := ORD(R[param1] < R[param2])
|opLTC: R[param1] := ORD(R[param1] < param2)
|opLE: R[param1] := ORD(R[param1] <= R[param2])
|opLEC: R[param1] := ORD(R[param1] <= param2)
|opGT: R[param1] := ORD(R[param1] > R[param2])
|opGTC: R[param1] := ORD(R[param1] > param2)
|opGE: R[param1] := ORD(R[param1] >= R[param2])
|opGEC: R[param1] := ORD(R[param1] >= param2)
|opBT: R[param1] := ORD((R[param1] < R[param2]) & (R[param1] >= 0))
|opBTC: R[param1] := ORD((R[param1] < param2) & (R[param1] >= 0))
|opLEA: R[param1 MOD 256] := Sections[param1 DIV 256] + param2
(*|opLABEL:*)
|opSYSCALL: syscall(R[param1])
|opADDRC: R[param1 MOD 256] := R[param1 DIV 256] + param2
|opCMP: fl := R[param1] < R[param2]; fe := R[param1] = R[param2]; fb := fl & (R[param1] >= 0)
|opCMPC: fl := R[param1] < param2; fe := R[param1] = param2; fb := fl & (R[param1] >= 0)
|opJEQ: IF fe THEN cmd := Labels[param1] END
|opJNE: IF ~fe THEN cmd := Labels[param1] END
|opJLT: IF fl THEN cmd := Labels[param1] END
|opJLE: IF fl OR fe THEN cmd := Labels[param1] END
|opJGT: IF ~fl & ~fe THEN cmd := Labels[param1] END
|opJGE: IF ~fl THEN cmd := Labels[param1] END
|opSEQ: R[param1] := ORD(fe)
|opSNE: R[param1] := ORD(~fe)
|opSLT: R[param1] := ORD(fl)
|opSLE: R[param1] := ORD(fl OR fe)
|opSGT: R[param1] := ORD(~fl & ~fe)
|opSGE: R[param1] := ORD(~fl)
|opJBT: IF fb THEN cmd := Labels[param1] END
END;
cmd := cmd.next
END
@@ -385,9 +386,6 @@ BEGIN
|opLDW: String("LDW "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opPUSH: String("PUSH "); Reg(param1)
|opPUSHC: String("PUSH "); Hex(param1)
|opJGZ: String("JGZ "); RegL(param1, param2)
|opJZ: String("JZ "); RegL(param1, param2)
|opJNZ: String("JNZ "); RegL(param1, param2)
|opLLA: String("LLA "); RegL(param1, param2)
|opJGA: String("JGA "); Hex(param1); String(", L"); Hex(param2)
|opJLA: String("JLA "); Hex(param1); String(", L"); Hex(param2)
@@ -437,24 +435,25 @@ BEGIN
|opMINC: String("MIN "); RegC(param1, param2)
|opMAX: String("MAX "); Reg2(param1, param2)
|opMAXC: String("MAX "); RegC(param1, param2)
|opEQ: String("EQ "); Reg2(param1, param2)
|opEQC: String("EQ "); RegC(param1, param2)
|opNE: String("NE "); Reg2(param1, param2)
|opNEC: String("NE "); RegC(param1, param2)
|opLT: String("LT "); Reg2(param1, param2)
|opLTC: String("LT "); RegC(param1, param2)
|opLE: String("LE "); Reg2(param1, param2)
|opLEC: String("LE "); RegC(param1, param2)
|opGT: String("GT "); Reg2(param1, param2)
|opGTC: String("GT "); RegC(param1, param2)
|opGE: String("GE "); Reg2(param1, param2)
|opGEC: String("GE "); RegC(param1, param2)
|opBT: String("BT "); Reg2(param1, param2)
|opBTC: String("BT "); RegC(param1, param2)
|opLEA: String("LEA "); Reg(param1 MOD 256); String(", "); String(Names[param1 DIV 256]); String(" + "); Hex(param2)
|opADDRC: String("ADD "); Reg(param1 MOD 256); String(", "); Reg(param1 DIV 256); String(", "); Hex(param2)
|opLABEL: String("L"); Hex(param1); String(":")
|opSYSCALL: String("SYSCALL "); Reg(param1)
|opCMP: String("CMP "); Reg2(param1, param2)
|opCMPC: String("CMP "); RegC(param1, param2)
|opJEQ: String("JEQ L"); Hex(param1)
|opJNE: String("JNE L"); Hex(param1)
|opJLT: String("JLT L"); Hex(param1)
|opJLE: String("JLE L"); Hex(param1)
|opJGT: String("JGT L"); Hex(param1)
|opJGE: String("JGE L"); Hex(param1)
|opSEQ: String("SEQ "); Reg(param1)
|opSNE: String("SNE "); Reg(param1)
|opSLT: String("SLT "); Reg(param1)
|opSLE: String("SLE "); Reg(param1)
|opSGT: String("SGT "); Reg(param1)
|opSGE: String("SGE "); Reg(param1)
|opJBT: String("JBT L"); Hex(param1)
END;
Ln;
cmd := cmd.next
+33 -29
View File
@@ -33,14 +33,16 @@
Регистры
Пять 32-битных регистров:
Не меньше пяти 32-битных регистров:
R0, R1, R2 регистры общего назначения
BP(R3) указатель кадра стэка
SP(R4) указатель стэка (растет вниз)
Нет регистра флагов, нет регистра связи (адрес возврата передается через стэк),
регистр-счетчик команд (PC) -- скрытый.
R5, R6... регистры общего назначения (опционально)
Регистра связи нет (адрес возврата передается через стэк),
регистр-счетчик команд (PC) -- скрытый, регистр флагов -- скрытый.
Нет вещественных регистров, операции с плавающей точкой (single) эмулируются.
@@ -99,9 +101,13 @@
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)
JGZ Rn, L#hex 13 n hex IF Rn > 0 THEN goto L#hex
JZ Rn, L#hex 14 n hex IF Rn = 0 THEN goto L#hex
JNZ Rn, L#hex 15 n hex IF Rn # 0 THEN goto L#hex
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)
LEA Rn, GLOBAL + imm 14 n + 200H imm Rn := imm + address(GLOBAL)
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)
JNA imm, L#hex 16 imm hex IF R0 # imm THEN goto L#hex
JGA imm, L#hex 17 imm hex IF R0 > imm THEN goto L#hex
JLA imm, L#hex 18 imm hex IF R0 < imm THEN goto L#hex
@@ -150,29 +156,27 @@
MIN Rn, imm 61 n imm IF imm < Rn THEN Rn := imm
MAX Rn, Rm 62 n m IF Rm > Rn THEN Rn := Rm
MAX Rn, imm 63 n imm IF imm > Rn THEN Rn := imm
EQ Rn, Rm 64 n m Rn := ORD(Rn = Rm)
EQ Rn, imm 65 n imm Rn := ORD(Rn = imm)
NE Rn, Rm 66 n m Rn := ORD(Rn # Rm)
NE Rn, imm 67 n imm Rn := ORD(Rn # imm)
LT Rn, Rm 68 n m Rn := ORD(Rn < Rm)
LT Rn, imm 69 n imm Rn := ORD(Rn < imm)
LE Rn, Rm 70 n m Rn := ORD(Rn <= Rm)
LE Rn, imm 71 n imm Rn := ORD(Rn <= imm)
GT Rn, Rm 72 n m Rn := ORD(Rn > Rm)
GT Rn, imm 73 n imm Rn := ORD(Rn > imm)
GE Rn, Rm 74 n m Rn := ORD(Rn >= Rm)
GE Rn, imm 75 n imm Rn := ORD(Rn >= imm)
BT Rn, Rm 76 n m Rn := ORD((0 <= Rn) & (Rn < Rm))
BT Rn, imm 77 n imm Rn := ORD((0 <= Rn) & (Rn < imm))
LEA Rn, TYPES + imm 78 n + 000H imm Rn := imm + address(TYPES)
LEA Rn, STRINGS + imm 78 n + 100H imm Rn := imm + address(STRINGS)
LEA Rn, GLOBAL + imm 78 n + 200H imm Rn := imm + address(GLOBAL)
LEA Rn, HEAP + imm 78 n + 300H imm Rn := imm + address(HEAP)
LEA Rn, STACK + imm 78 n + 400H imm Rn := imm + address(STACK)
L#hex: 79 hex 0 метка:
SYSCALL Rn 80 n 0 системный вызов; Rn содержит адрес параметров
ADD Rn, Rm, imm 81 m*256 + n imm Rn := Rm + imm
LLA Rn, L#hex 82 n hex Rn := address(L#hex)
CMP Rn, Rm 64 n m сравнить Rn и Rm
CMP Rn, imm 65 n imm сравнить Rn и imm
SYSCALL Rn 67 n 0 системный вызов; Rn содержит адрес параметров
JBT L#hex 68 hex 0 перейти на метку L#hex, если "ниже"
ADD Rn, Rm, imm 69 m*256 + n imm Rn := Rm + imm
JEQ L#hex 70 hex 0 перейти на метку L#hex, если "равно"
JNE L#hex 71 hex 0 перейти на метку L#hex, если "не равно"
JLT L#hex 72 hex 0 перейти на метку L#hex, если "меньше"
JGЕ L#hex 73 hex 0 перейти на метку L#hex, если "не меньше"
JGT L#hex 74 hex 0 перейти на метку L#hex, если "больше"
JLЕ L#hex 75 hex 0 перейти на метку L#hex, если "не больше"
SEQ Rn 76 n 0 если "равно": Rn := 1, иначе Rn := 0
SNE Rn 77 n 0 если "не равно": Rn := 1, иначе Rn := 0
SLT Rn 78 n 0 если "меньше": Rn := 1, иначе Rn := 0
SGЕ Rn 79 n 0 если "не меньше": Rn := 1, иначе Rn := 0
SGT Rn 80 n 0 если "больше": Rn := 1, иначе Rn := 0
SLЕ Rn 81 n 0 если "не больше": Rn := 1, иначе Rn := 0
Команда CMP сохраняет результат сравнения в скрытом регистре, этот результат используется
в командах перехода по условию (JEQ, JNE, JLT, JGE, JGT, JLE, JBT) а также в командах
установки регистра по условию (SEQ, SNE, SLT, SGE, SGT, SLE).
---------------------------------------------------------------------------------------------------