mirror of
https://github.com/AntKrotov/oberon-07-compiler.git
synced 2026-10-05 09:45:47 +00:00
v1.36
исправлена ошибка в работе с вещественными регистрами
This commit is contained in:
1 parent
e663c9ee33
commit
1df858a3b9
9 files changed
+231
-184
No files matched your search
@@ -1 +0,0 @@
|
||||
*.exe
|
||||
Binary file not shown.
+56
-11
@@ -8,7 +8,7 @@
|
||||
MODULE AMD64;
|
||||
|
||||
IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG, TARGETS,
|
||||
REG, C := CONSOLE, UTILS, S := STRINGS, PE32, ELF, X86;
|
||||
REG, C := CONSOLE, UTILS, S := STRINGS, PE32, ELF, X86, ERRORS;
|
||||
|
||||
|
||||
CONST
|
||||
@@ -27,6 +27,8 @@ CONST
|
||||
rsi = 6;
|
||||
rdi = 7;
|
||||
|
||||
MAX_XMM = 5;
|
||||
|
||||
je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H;
|
||||
|
||||
sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
|
||||
@@ -38,6 +40,8 @@ CONST
|
||||
sBSS = BIN.PICBSS;
|
||||
sIMP = BIN.PICIMP;
|
||||
|
||||
FPR_ERR = 41;
|
||||
|
||||
|
||||
TYPE
|
||||
|
||||
@@ -65,6 +69,8 @@ VAR
|
||||
Win64RegPar: ARRAY 4 OF INTEGER;
|
||||
SystemVRegPar: ARRAY 6 OF INTEGER;
|
||||
|
||||
Xmm: ARRAY 1000 OF INTEGER;
|
||||
|
||||
|
||||
PROCEDURE OutByte (b: BYTE);
|
||||
BEGIN
|
||||
@@ -830,6 +836,8 @@ VAR
|
||||
|
||||
regVar: BOOLEAN;
|
||||
|
||||
fname: PATHS.PATH;
|
||||
|
||||
BEGIN
|
||||
xmm := -1;
|
||||
cmd := commands.first(COMMAND);
|
||||
@@ -842,6 +850,9 @@ BEGIN
|
||||
|
||||
CASE opcode OF
|
||||
|
||||
|IL.opFNAME:
|
||||
fname := cmd(IL.FNAMECMD).fname
|
||||
|
||||
|IL.opJMP:
|
||||
X86.jmp(param1)
|
||||
|
||||
@@ -897,18 +908,18 @@ BEGIN
|
||||
pushc(param2)
|
||||
|
||||
|IL.opPRECALL:
|
||||
n := param2;
|
||||
IF (param1 # 0) & (n # 0) THEN
|
||||
PushAll(0);
|
||||
IF (param2 # 0) & (xmm >= 0) THEN
|
||||
subrc(rsp, 8)
|
||||
END;
|
||||
WHILE n > 0 DO
|
||||
INC(Xmm[0]);
|
||||
Xmm[Xmm[0]] := xmm + 1;
|
||||
WHILE xmm >= 0 DO
|
||||
subrc(rsp, 8);
|
||||
movsdmr(rsp, 0, xmm);
|
||||
DEC(xmm);
|
||||
DEC(n)
|
||||
DEC(xmm)
|
||||
END;
|
||||
ASSERT(xmm = -1);
|
||||
PushAll(0)
|
||||
ASSERT(xmm = -1)
|
||||
|
||||
|IL.opWIN64ALIGN16:
|
||||
ASSERT(rax IN R.regs);
|
||||
@@ -929,13 +940,17 @@ BEGIN
|
||||
|IL.opRESF:
|
||||
ASSERT(xmm = -1);
|
||||
INC(xmm);
|
||||
n := param2;
|
||||
n := Xmm[Xmm[0]]; DEC(Xmm[0]);
|
||||
IF n > 0 THEN
|
||||
movsdmr(rsp, n * 8, xmm);
|
||||
movsdmr(rsp, n * 8, 0);
|
||||
DEC(xmm);
|
||||
INC(n)
|
||||
END;
|
||||
|
||||
IF xmm + n > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
|
||||
WHILE n > 0 DO
|
||||
INC(xmm);
|
||||
movsdrm(xmm, rsp, 0);
|
||||
@@ -945,8 +960,9 @@ BEGIN
|
||||
|
||||
|IL.opRES:
|
||||
ASSERT(R.top = -1);
|
||||
ASSERT(xmm = -1);
|
||||
GetRegA;
|
||||
n := param2;
|
||||
n := Xmm[Xmm[0]]; DEC(Xmm[0]);
|
||||
WHILE n > 0 DO
|
||||
INC(xmm);
|
||||
movsdrm(xmm, rsp, 0);
|
||||
@@ -1172,11 +1188,15 @@ BEGIN
|
||||
n := param2 * 8;
|
||||
next := cmd.next(COMMAND);
|
||||
IF (next.opcode = IL.opSAVEF) OR (next.opcode = IL.opSAVEFI) THEN
|
||||
ASSERT(xmm >= 0);
|
||||
movsdmr(rbp, n, xmm);
|
||||
DEC(xmm);
|
||||
cmd := next
|
||||
ELSIF next.opcode = IL.opLOADF THEN
|
||||
INC(xmm);
|
||||
IF xmm > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, next.param1, next.param2, FPR_ERR)
|
||||
END;
|
||||
movsdrm(xmm, rbp, n);
|
||||
cmd := next
|
||||
ELSE
|
||||
@@ -2050,10 +2070,14 @@ BEGIN
|
||||
|IL.opLOADF:
|
||||
UnOp(reg1);
|
||||
INC(xmm);
|
||||
IF xmm > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
movsdrm(xmm, reg1, 0);
|
||||
drop
|
||||
|
||||
|IL.opPUSHF:
|
||||
ASSERT(xmm >= 0);
|
||||
subrc(rsp, 8);
|
||||
movsdmr(rsp, 0, xmm);
|
||||
DEC(xmm)
|
||||
@@ -2061,6 +2085,9 @@ BEGIN
|
||||
|IL.opCONSTF:
|
||||
float := cmd.float;
|
||||
INC(xmm);
|
||||
IF xmm > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
reg1 := GetAnyReg();
|
||||
lea(reg1, Numbers_Offs + Numbers_Count * 8, sDATA);
|
||||
movsdrm(xmm, reg1, 0);
|
||||
@@ -2068,38 +2095,46 @@ BEGIN
|
||||
NewNumber(UTILS.splitf(float, a, b))
|
||||
|
||||
|IL.opSAVEF, IL.opSAVEFI:
|
||||
ASSERT(xmm >= 0);
|
||||
UnOp(reg1);
|
||||
movsdmr(reg1, 0, xmm);
|
||||
DEC(xmm);
|
||||
drop
|
||||
|
||||
|IL.opADDF:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(58H, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opSUBF:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(5CH, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opSUBFI:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(5CH, xmm, xmm - 1);
|
||||
opxx(10H, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opMULF:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(59H, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opDIVF:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(5EH, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opDIVFI:
|
||||
ASSERT(xmm >= 1);
|
||||
opxx(5EH, xmm, xmm - 1);
|
||||
opxx(10H, xmm - 1, xmm);
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opUMINF:
|
||||
ASSERT(xmm >= 0);
|
||||
reg1 := GetAnyReg();
|
||||
lea(reg1, Numbers_Offs, sDATA);
|
||||
OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* xorpd xmm, xmmword[reg1] *)
|
||||
@@ -2107,6 +2142,7 @@ BEGIN
|
||||
drop
|
||||
|
||||
|IL.opFABS:
|
||||
ASSERT(xmm >= 0);
|
||||
reg1 := GetAnyReg();
|
||||
lea(reg1, Numbers_Offs + 16, sDATA);
|
||||
OutByte3(66H, 40H + reg1 DIV 8 + (xmm DIV 8) * 4, 0FH); (* andpd xmm, xmmword[reg1] *)
|
||||
@@ -2116,11 +2152,15 @@ BEGIN
|
||||
|IL.opFLT:
|
||||
UnOp(reg1);
|
||||
INC(xmm);
|
||||
IF xmm > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); (* cvtsi2sd xmm, reg1 *)
|
||||
OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8);
|
||||
drop
|
||||
|
||||
|IL.opFLOOR:
|
||||
ASSERT(xmm >= 0);
|
||||
reg1 := GetAnyReg();
|
||||
subrc(rsp, 8);
|
||||
OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H); (* stmxcsr dword[rsp+4]; *)
|
||||
@@ -2135,11 +2175,15 @@ BEGIN
|
||||
DEC(xmm)
|
||||
|
||||
|IL.opEQF .. IL.opGEF:
|
||||
ASSERT(xmm >= 1);
|
||||
fcmp(opcode, xmm);
|
||||
DEC(xmm, 2)
|
||||
|
||||
|IL.opINF:
|
||||
INC(xmm);
|
||||
IF xmm > MAX_XMM THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
reg1 := GetAnyReg();
|
||||
lea(reg1, Numbers_Offs + 32, sDATA);
|
||||
movsdrm(xmm, reg1, 0);
|
||||
@@ -2621,6 +2665,7 @@ VAR
|
||||
path, modname, ext: PATHS.PATH;
|
||||
|
||||
BEGIN
|
||||
Xmm[0] := 0;
|
||||
tcount := CHL.Length(IL.codes.types);
|
||||
|
||||
Win64RegPar[0] := rcx;
|
||||
|
||||
+23
-110
@@ -7,7 +7,7 @@
|
||||
|
||||
MODULE IL;
|
||||
|
||||
IMPORT LISTS, SCAN, STRINGS, CHL := CHUNKLISTS, C := COLLECTIONS, TARGETS;
|
||||
IMPORT LISTS, SCAN, STRINGS, CHL := CHUNKLISTS, C := COLLECTIONS, TARGETS, PATHS;
|
||||
|
||||
|
||||
CONST
|
||||
@@ -79,6 +79,7 @@ CONST
|
||||
opSAVE16C* = 213; opWCHR* = 214; opHANDLER* = 215;
|
||||
|
||||
opSYSVCALL* = 216; opSYSVCALLI* = 217; opSYSVCALLP* = 218; opSYSVALIGN16* = 219; opWIN64ALIGN16* = 220;
|
||||
opFNAME* = 221;
|
||||
|
||||
|
||||
opSADR_PARAM* = -1; opLOAD64_PARAM* = -2; opLLOAD64_PARAM* = -3; opGLOAD64_PARAM* = -4;
|
||||
@@ -149,6 +150,12 @@ TYPE
|
||||
|
||||
END;
|
||||
|
||||
FNAMECMD* = POINTER TO RECORD (COMMAND)
|
||||
|
||||
fname*: PATHS.PATH
|
||||
|
||||
END;
|
||||
|
||||
CMDSTACK = POINTER TO RECORD
|
||||
|
||||
data: ARRAY 1000 OF COMMAND;
|
||||
@@ -199,7 +206,6 @@ TYPE
|
||||
charoffs: ARRAY 256 OF INTEGER;
|
||||
wcharoffs: ARRAY 65536 OF INTEGER;
|
||||
|
||||
fregs: INTEGER;
|
||||
wstr: ARRAY 4*1024 OF WCHAR
|
||||
END;
|
||||
|
||||
@@ -208,7 +214,7 @@ VAR
|
||||
|
||||
codes*: CODES;
|
||||
little: BOOLEAN;
|
||||
numRegsFloat, CPU: INTEGER;
|
||||
CPU: INTEGER;
|
||||
|
||||
commands, variables: C.COLLECTION;
|
||||
|
||||
@@ -684,14 +690,6 @@ BEGIN
|
||||
END New;
|
||||
|
||||
|
||||
PROCEDURE fcmp* (opcode: INTEGER);
|
||||
BEGIN
|
||||
AddCmd(opcode, 0);
|
||||
DEC(codes.fregs, 2);
|
||||
ASSERT(codes.fregs >= 0)
|
||||
END fcmp;
|
||||
|
||||
|
||||
PROCEDURE not*;
|
||||
VAR
|
||||
prev: COMMAND;
|
||||
@@ -899,44 +897,10 @@ BEGIN
|
||||
AddCmd0(opSAVEFI)
|
||||
ELSE
|
||||
AddCmd0(opSAVEF)
|
||||
END;
|
||||
DEC(codes.fregs);
|
||||
ASSERT(codes.fregs >= 0)
|
||||
END
|
||||
END savef;
|
||||
|
||||
|
||||
PROCEDURE pushf*;
|
||||
BEGIN
|
||||
AddCmd0(opPUSHF);
|
||||
DEC(codes.fregs);
|
||||
ASSERT(codes.fregs >= 0)
|
||||
END pushf;
|
||||
|
||||
|
||||
PROCEDURE loadf* (): BOOLEAN;
|
||||
BEGIN
|
||||
AddCmd0(opLOADF);
|
||||
INC(codes.fregs)
|
||||
RETURN codes.fregs < numRegsFloat
|
||||
END loadf;
|
||||
|
||||
|
||||
PROCEDURE inf* (): BOOLEAN;
|
||||
BEGIN
|
||||
AddCmd0(opINF);
|
||||
INC(codes.fregs)
|
||||
RETURN codes.fregs < numRegsFloat
|
||||
END inf;
|
||||
|
||||
|
||||
PROCEDURE fbinop* (opcode: INTEGER);
|
||||
BEGIN
|
||||
AddCmd0(opcode);
|
||||
DEC(codes.fregs);
|
||||
ASSERT(codes.fregs > 0)
|
||||
END fbinop;
|
||||
|
||||
|
||||
PROCEDURE saves* (offset, length: INTEGER);
|
||||
BEGIN
|
||||
AddCmd2(opSAVES, length, offset)
|
||||
@@ -953,22 +917,6 @@ BEGIN
|
||||
END abs;
|
||||
|
||||
|
||||
PROCEDURE floor*;
|
||||
BEGIN
|
||||
AddCmd0(opFLOOR);
|
||||
DEC(codes.fregs);
|
||||
ASSERT(codes.fregs >= 0)
|
||||
END floor;
|
||||
|
||||
|
||||
PROCEDURE flt* (): BOOLEAN;
|
||||
BEGIN
|
||||
AddCmd0(opFLT);
|
||||
INC(codes.fregs)
|
||||
RETURN codes.fregs < numRegsFloat
|
||||
END flt;
|
||||
|
||||
|
||||
PROCEDURE shift_minmax* (op: CHAR);
|
||||
BEGIN
|
||||
CASE op OF
|
||||
@@ -1014,7 +962,7 @@ BEGIN
|
||||
END len;
|
||||
|
||||
|
||||
PROCEDURE Float* (r: REAL);
|
||||
PROCEDURE Float* (r: REAL; line, col: INTEGER);
|
||||
VAR
|
||||
cmd: COMMAND;
|
||||
|
||||
@@ -1022,45 +970,12 @@ BEGIN
|
||||
cmd := NewCmd();
|
||||
cmd.opcode := opCONSTF;
|
||||
cmd.float := r;
|
||||
insert(codes.last, cmd);
|
||||
INC(codes.fregs);
|
||||
ASSERT(codes.fregs <= numRegsFloat)
|
||||
cmd.param1 := line;
|
||||
cmd.param2 := col;
|
||||
insert(codes.last, cmd)
|
||||
END Float;
|
||||
|
||||
|
||||
PROCEDURE precall* (flt: BOOLEAN): INTEGER;
|
||||
VAR
|
||||
res: INTEGER;
|
||||
BEGIN
|
||||
res := codes.fregs;
|
||||
AddCmd2(opPRECALL, ORD(flt), res);
|
||||
codes.fregs := 0
|
||||
RETURN res
|
||||
END precall;
|
||||
|
||||
|
||||
PROCEDURE resf* (fregs: INTEGER): BOOLEAN;
|
||||
BEGIN
|
||||
AddCmd(opRESF, fregs);
|
||||
codes.fregs := fregs + 1
|
||||
RETURN codes.fregs < numRegsFloat
|
||||
END resf;
|
||||
|
||||
|
||||
PROCEDURE res* (fregs: INTEGER);
|
||||
BEGIN
|
||||
AddCmd(opRES, fregs);
|
||||
codes.fregs := fregs
|
||||
END res;
|
||||
|
||||
|
||||
PROCEDURE retf*;
|
||||
BEGIN
|
||||
DEC(codes.fregs);
|
||||
ASSERT(codes.fregs = 0)
|
||||
END retf;
|
||||
|
||||
|
||||
PROCEDURE drop*;
|
||||
BEGIN
|
||||
AddCmd0(opDROP)
|
||||
@@ -1086,10 +1001,16 @@ BEGIN
|
||||
END case;
|
||||
|
||||
|
||||
PROCEDURE caset* (a, label: INTEGER);
|
||||
PROCEDURE fname* (name: PATHS.PATH);
|
||||
VAR
|
||||
cmd: FNAMECMD;
|
||||
|
||||
BEGIN
|
||||
AddCmd2(opCASET, label, a)
|
||||
END caset;
|
||||
NEW(cmd);
|
||||
cmd.opcode := opFNAME;
|
||||
cmd.fname := name;
|
||||
insert(codes.last, cmd)
|
||||
END fname;
|
||||
|
||||
|
||||
PROCEDURE AddExp* (label: INTEGER; name: SCAN.LEXSTR);
|
||||
@@ -1169,12 +1090,6 @@ BEGIN
|
||||
|
||||
CPU := pCPU;
|
||||
little := TRUE;
|
||||
CASE CPU OF
|
||||
|TARGETS.cpuAMD64: numRegsFloat := 6
|
||||
|TARGETS.cpuX86: numRegsFloat := 8
|
||||
|TARGETS.cpuMSP430: numRegsFloat := 0
|
||||
|TARGETS.cpuTHUMB: numRegsFloat := 256
|
||||
END;
|
||||
|
||||
NEW(codes.begcall);
|
||||
codes.begcall.top := -1;
|
||||
@@ -1194,8 +1109,6 @@ BEGIN
|
||||
|
||||
codes.lcount := 0;
|
||||
|
||||
codes.fregs := 0;
|
||||
|
||||
FOR i := 0 TO LEN(codes.charoffs) - 1 DO
|
||||
codes.charoffs[i] := -1
|
||||
END;
|
||||
|
||||
@@ -1204,6 +1204,10 @@ BEGIN
|
||||
END;
|
||||
CONSOLE.Ln;
|
||||
|
||||
IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
|
||||
IL.fname(parser.fname)
|
||||
END;
|
||||
|
||||
label := IL.NewLabel();
|
||||
IL.AddJmpCmd(IL.opJMP, label);
|
||||
|
||||
|
||||
+56
-50
@@ -358,7 +358,17 @@ BEGIN
|
||||
END CheckRange;
|
||||
|
||||
|
||||
PROCEDURE assign (e: PARS.EXPR; VarType: PROG.TYPE_; line: INTEGER): BOOLEAN;
|
||||
PROCEDURE Float (parser: PARS.PARSER; e: PARS.EXPR);
|
||||
VAR
|
||||
pos: PARS.POSITION;
|
||||
|
||||
BEGIN
|
||||
getpos(parser, pos);
|
||||
IL.Float(ARITH.Float(e.value), pos.line, pos.col)
|
||||
END Float;
|
||||
|
||||
|
||||
PROCEDURE assign (parser: PARS.PARSER; e: PARS.EXPR; VarType: PROG.TYPE_; line: INTEGER): BOOLEAN;
|
||||
VAR
|
||||
res: BOOLEAN;
|
||||
label: INTEGER;
|
||||
@@ -414,7 +424,7 @@ BEGIN
|
||||
END
|
||||
ELSIF isReal(e) & (VarType = tREAL) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value))
|
||||
Float(parser, e)
|
||||
END;
|
||||
IL.savef(e.obj = eCONST)
|
||||
ELSIF isChar(e) & (VarType = tCHAR) THEN
|
||||
@@ -592,8 +602,8 @@ BEGIN
|
||||
PARS.check(assigncomp(e, p.type), pos, 66);
|
||||
IF e.obj = eCONST THEN
|
||||
IF e.type = tREAL THEN
|
||||
IL.Float(ARITH.Float(e.value));
|
||||
IL.pushf
|
||||
Float(parser, e);
|
||||
IL.AddCmd0(IL.opPUSHF)
|
||||
ELSIF e.type.typ = PROG.tNIL THEN
|
||||
IL.Const(0);
|
||||
IL.Param1
|
||||
@@ -626,7 +636,7 @@ BEGIN
|
||||
IL.PushImpProc(e.ident.import);
|
||||
IL.Param1
|
||||
ELSIF isExpr(e) & (e.type = tREAL) THEN
|
||||
IL.pushf
|
||||
IL.AddCmd0(IL.opPUSHF)
|
||||
ELSE
|
||||
IF (p.type = tBYTE) & (e.type = tINTEGER) & (chkBYTE IN Options.checking) THEN
|
||||
CheckRange(256, pos.line, errBYTE)
|
||||
@@ -899,7 +909,7 @@ BEGIN
|
||||
PARS.check(e2.type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
|
||||
IF e2.obj = eCONST THEN
|
||||
IF e2.type = tREAL THEN
|
||||
IL.Float(ARITH.Float(e2.value));
|
||||
Float(parser, e2);
|
||||
IL.setlast(endcall.prev(IL.COMMAND));
|
||||
IL.savef(FALSE)
|
||||
ELSE
|
||||
@@ -1079,7 +1089,7 @@ BEGIN
|
||||
IF e.obj = eCONST THEN
|
||||
PARS.check(ARITH.floor(e.value), pos, 39)
|
||||
ELSE
|
||||
IL.floor
|
||||
IL.AddCmd0(IL.opFLOOR)
|
||||
END
|
||||
|
||||
|PROG.stFLT:
|
||||
@@ -1089,7 +1099,7 @@ BEGIN
|
||||
IF e.obj = eCONST THEN
|
||||
ARITH.flt(e.value)
|
||||
ELSE
|
||||
PARS.check(IL.flt(), pos, 41)
|
||||
IL.AddCmd2(IL.opFLT, pos.line, pos.col)
|
||||
END
|
||||
|
||||
|PROG.stLEN:
|
||||
@@ -1202,7 +1212,7 @@ BEGIN
|
||||
e.type := tINTEGER
|
||||
|
||||
|PROG.sysINF:
|
||||
PARS.check(IL.inf(), pos, 41);
|
||||
IL.AddCmd2(IL.opINF, pos.line, pos.col);
|
||||
e.obj := eEXPR;
|
||||
e.type := tREAL
|
||||
|
||||
@@ -1585,7 +1595,7 @@ BEGIN
|
||||
END designator;
|
||||
|
||||
|
||||
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG.TYPE_; isfloat: BOOLEAN; VAR fregs: INTEGER; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN);
|
||||
PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG.TYPE_; isfloat: BOOLEAN; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN);
|
||||
VAR
|
||||
cconv,
|
||||
parSize,
|
||||
@@ -1610,7 +1620,7 @@ BEGIN
|
||||
fparSize := 0
|
||||
END;
|
||||
IL.setlast(begcall);
|
||||
fregs := IL.precall(isfloat);
|
||||
IL.AddCmd(IL.opPRECALL, ORD(isfloat));
|
||||
|
||||
IF cconv IN {PROG._ccall16, PROG.ccall16} THEN
|
||||
IL.AddCmd(IL.opALIGN16, parSize)
|
||||
@@ -1643,11 +1653,14 @@ BEGIN
|
||||
IL.AddCmd(IL.opCLEANUP, parSize)
|
||||
END;
|
||||
|
||||
IF ~CallStat THEN
|
||||
IF CallStat THEN
|
||||
IL.AddCmd0(IL.opRES);
|
||||
IL.drop
|
||||
ELSE
|
||||
IF isfloat THEN
|
||||
PARS.check(IL.resf(fregs), pos, 41)
|
||||
IL.AddCmd2(IL.opRESF, pos.line, pos.col)
|
||||
ELSE
|
||||
IL.res(fregs)
|
||||
IL.AddCmd0(IL.opRES)
|
||||
END
|
||||
END
|
||||
END ProcCall;
|
||||
@@ -1786,14 +1799,13 @@ VAR
|
||||
pos: PARS.POSITION;
|
||||
e1: PARS.EXPR;
|
||||
isfloat: BOOLEAN;
|
||||
fregs: INTEGER;
|
||||
|
||||
|
||||
PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION);
|
||||
BEGIN
|
||||
IF ~(e.type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
|
||||
IF e.type = tREAL THEN
|
||||
PARS.check(IL.loadf(), pos, 41)
|
||||
IL.AddCmd2(IL.opLOADF, pos.line, pos.col)
|
||||
ELSE
|
||||
IL.load(e.type.size)
|
||||
END
|
||||
@@ -1839,9 +1851,9 @@ VAR
|
||||
PARS.check(e.type # NIL, pos, 59);
|
||||
isfloat := e.type = tREAL;
|
||||
IF e1.obj IN {ePROC, eIMP} THEN
|
||||
ProcCall(e1, e1.ident.type, isfloat, fregs, parser, pos, FALSE)
|
||||
ProcCall(e1, e1.ident.type, isfloat, parser, pos, FALSE)
|
||||
ELSIF isExpr(e1) THEN
|
||||
ProcCall(e1, e1.type, isfloat, fregs, parser, pos, FALSE)
|
||||
ProcCall(e1, e1.type, isfloat, parser, pos, FALSE)
|
||||
END
|
||||
END;
|
||||
IL.popBegEnd(begcall, endcall)
|
||||
@@ -1927,11 +1939,11 @@ VAR
|
||||
END
|
||||
ELSIF isReal(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value))
|
||||
Float(parser, e)
|
||||
ELSIF e1.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e1.value))
|
||||
Float(parser, e1)
|
||||
END;
|
||||
IL.fbinop(IL.opMULF)
|
||||
IL.AddCmd0(IL.opMULF)
|
||||
ELSIF isSet(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IL.AddCmd(IL.opMULSC, ARITH.Int(e.value))
|
||||
@@ -1959,13 +1971,13 @@ VAR
|
||||
ELSE
|
||||
IF isReal(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value));
|
||||
IL.fbinop(IL.opDIVFI)
|
||||
Float(parser, e);
|
||||
IL.AddCmd0(IL.opDIVFI)
|
||||
ELSIF e1.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e1.value));
|
||||
IL.fbinop(IL.opDIVF)
|
||||
Float(parser, e1);
|
||||
IL.AddCmd0(IL.opDIVF)
|
||||
ELSE
|
||||
IL.fbinop(IL.opDIVF)
|
||||
IL.AddCmd0(IL.opDIVF)
|
||||
END
|
||||
ELSIF isSet(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
@@ -2155,13 +2167,13 @@ VAR
|
||||
END
|
||||
ELSIF isReal(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value));
|
||||
IL.fbinop(IL.opADDF - ORD(minus))
|
||||
Float(parser, e);
|
||||
IL.AddCmd0(IL.opADDF - ORD(minus))
|
||||
ELSIF e1.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e1.value));
|
||||
IL.fbinop(IL.opADDF + ORD(minus))
|
||||
Float(parser, e1);
|
||||
IL.AddCmd0(IL.opADDF + ORD(minus))
|
||||
ELSE
|
||||
IL.fbinop(IL.opADDF + ORD(minus))
|
||||
IL.AddCmd0(IL.opADDF + ORD(minus))
|
||||
END
|
||||
ELSIF isSet(e) THEN
|
||||
IF e.obj = eCONST THEN
|
||||
@@ -2365,11 +2377,11 @@ BEGIN
|
||||
ARITH.relation(e.value, e1.value, cmp, error)
|
||||
ELSE
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value))
|
||||
Float(parser, e)
|
||||
ELSIF e1.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e1.value))
|
||||
Float(parser, e1)
|
||||
END;
|
||||
IL.fcmp(IL.opEQF + cmp)
|
||||
IL.AddCmd0(IL.opEQF + cmp)
|
||||
END
|
||||
|
||||
ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
|
||||
@@ -2465,13 +2477,13 @@ BEGIN
|
||||
ARITH.relation(e.value, e1.value, cmp, error)
|
||||
ELSE
|
||||
IF e.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e.value));
|
||||
IL.fcmp(IL.opEQF + invcmpcode(op))
|
||||
Float(parser, e);
|
||||
IL.AddCmd0(IL.opEQF + invcmpcode(op))
|
||||
ELSIF e1.obj = eCONST THEN
|
||||
IL.Float(ARITH.Float(e1.value));
|
||||
IL.fcmp(IL.opEQF + cmp)
|
||||
Float(parser, e1);
|
||||
IL.AddCmd0(IL.opEQF + cmp)
|
||||
ELSE
|
||||
IL.fcmp(IL.opEQF + cmp)
|
||||
IL.AddCmd0(IL.opEQF + cmp)
|
||||
END
|
||||
END
|
||||
|
||||
@@ -2541,7 +2553,6 @@ VAR
|
||||
pos: PARS.POSITION;
|
||||
line: INTEGER;
|
||||
call: BOOLEAN;
|
||||
fregs: INTEGER;
|
||||
|
||||
BEGIN
|
||||
getpos(parser, pos);
|
||||
@@ -2562,7 +2573,7 @@ BEGIN
|
||||
|
||||
IL.setlast(endcall.prev(IL.COMMAND));
|
||||
|
||||
PARS.check(assign(e1, e.type, line), pos, 91);
|
||||
PARS.check(assign(parser, e1, e.type, line), pos, 91);
|
||||
IF e1.obj = ePROC THEN
|
||||
PARS.check(e1.ident.global, pos, 85)
|
||||
END;
|
||||
@@ -2588,9 +2599,9 @@ BEGIN
|
||||
|
||||
IF call THEN
|
||||
IF e.obj IN {ePROC, eIMP} THEN
|
||||
ProcCall(e, e.ident.type, FALSE, fregs, parser, pos, TRUE)
|
||||
ProcCall(e, e.ident.type, FALSE, parser, pos, TRUE)
|
||||
ELSIF isExpr(e) THEN
|
||||
ProcCall(e, e.type, FALSE, fregs, parser, pos, TRUE)
|
||||
ProcCall(e, e.type, FALSE, parser, pos, TRUE)
|
||||
END
|
||||
END;
|
||||
|
||||
@@ -2956,8 +2967,7 @@ VAR
|
||||
PROCEDURE TableT (node: AVL.NODE);
|
||||
BEGIN
|
||||
IF node # NIL THEN
|
||||
IL.caset(node.data(CASE_LABEL).range.a, node.data(CASE_LABEL).variant);
|
||||
|
||||
IL.AddCmd2(IL.opCASET, node.data(CASE_LABEL).variant, node.data(CASE_LABEL).range.a);
|
||||
TableT(node.left);
|
||||
TableT(node.right)
|
||||
END
|
||||
@@ -3201,7 +3211,7 @@ BEGIN
|
||||
IF res THEN
|
||||
IF e.obj = eCONST THEN
|
||||
IF e.type = tREAL THEN
|
||||
IL.Float(ARITH.Float(e.value))
|
||||
Float(parser, e)
|
||||
ELSIF e.type.typ = PROG.tNIL THEN
|
||||
IL.Const(0)
|
||||
ELSE
|
||||
@@ -3214,10 +3224,6 @@ BEGIN
|
||||
IL.PushProc(e.ident.proc.label)
|
||||
ELSIF e.obj = eIMP THEN
|
||||
IL.PushImpProc(e.ident.import)
|
||||
END;
|
||||
|
||||
IF e.type = tREAL THEN
|
||||
IL.retf
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ CONST
|
||||
max32* = 2147483647;
|
||||
|
||||
vMajor* = 1;
|
||||
vMinor* = 35;
|
||||
vMinor* = 36;
|
||||
|
||||
FILE_EXT* = ".ob07";
|
||||
RTL_NAME* = "RTL";
|
||||
|
||||
+91
-11
@@ -8,7 +8,7 @@
|
||||
MODULE X86;
|
||||
|
||||
IMPORT IL, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, PROG,
|
||||
CHL := CHUNKLISTS, PATHS, TARGETS;
|
||||
CHL := CHUNKLISTS, PATHS, TARGETS, ERRORS;
|
||||
|
||||
|
||||
CONST
|
||||
@@ -22,6 +22,8 @@ CONST
|
||||
esp = 4;
|
||||
ebp = 5;
|
||||
|
||||
MAX_FR = 7;
|
||||
|
||||
sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
|
||||
|
||||
je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
|
||||
@@ -29,6 +31,8 @@ CONST
|
||||
|
||||
CODECHUNK = 8;
|
||||
|
||||
FPR_ERR = 41;
|
||||
|
||||
|
||||
TYPE
|
||||
|
||||
@@ -92,6 +96,8 @@ VAR
|
||||
|
||||
tcount: INTEGER;
|
||||
|
||||
FR: ARRAY 1000 OF INTEGER;
|
||||
|
||||
|
||||
PROCEDURE OutByte* (n: BYTE);
|
||||
VAR
|
||||
@@ -722,7 +728,7 @@ PROCEDURE translate (pic: BOOLEAN; stroffs: INTEGER);
|
||||
VAR
|
||||
cmd, next: COMMAND;
|
||||
|
||||
reg1, reg2: INTEGER;
|
||||
reg1, reg2, fr: INTEGER;
|
||||
|
||||
n, a, b, label, cc: INTEGER;
|
||||
|
||||
@@ -730,9 +736,13 @@ VAR
|
||||
|
||||
float: REAL;
|
||||
|
||||
fname: PATHS.PATH;
|
||||
|
||||
BEGIN
|
||||
cmd := IL.codes.commands.first(COMMAND);
|
||||
|
||||
fr := -1;
|
||||
|
||||
WHILE cmd # NIL DO
|
||||
|
||||
param1 := cmd.param1;
|
||||
@@ -742,6 +752,9 @@ BEGIN
|
||||
|
||||
CASE opcode OF
|
||||
|
||||
|IL.opFNAME:
|
||||
fname := cmd(IL.FNAMECMD).fname
|
||||
|
||||
|IL.opJMP:
|
||||
jmp(param1)
|
||||
|
||||
@@ -766,16 +779,18 @@ BEGIN
|
||||
ASSERT(R.top = -1)
|
||||
|
||||
|IL.opPRECALL:
|
||||
n := param2;
|
||||
IF (param1 # 0) & (n # 0) THEN
|
||||
PushAll(0);
|
||||
IF (param2 # 0) & (fr >= 0) THEN
|
||||
subrc(esp, 8)
|
||||
END;
|
||||
WHILE n > 0 DO
|
||||
INC(FR[0]);
|
||||
FR[FR[0]] := fr + 1;
|
||||
WHILE fr >= 0 DO
|
||||
subrc(esp, 8);
|
||||
OutByte3(0DDH, 01CH, 024H); (* fstp qword[esp] *)
|
||||
DEC(n)
|
||||
DEC(fr)
|
||||
END;
|
||||
PushAll(0)
|
||||
ASSERT(fr = -1)
|
||||
|
||||
|IL.opALIGN16:
|
||||
ASSERT(eax IN R.regs);
|
||||
@@ -789,25 +804,35 @@ BEGIN
|
||||
|
||||
|IL.opRES:
|
||||
ASSERT(R.top = -1);
|
||||
ASSERT(fr = -1);
|
||||
GetRegA;
|
||||
n := param2;
|
||||
n := FR[FR[0]]; DEC(FR[0]);
|
||||
WHILE n > 0 DO
|
||||
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
|
||||
addrc(esp, 8);
|
||||
INC(fr);
|
||||
DEC(n)
|
||||
END
|
||||
|
||||
|IL.opRESF:
|
||||
n := param2;
|
||||
ASSERT(fr = -1);
|
||||
INC(fr);
|
||||
n := FR[FR[0]]; DEC(FR[0]);
|
||||
IF n > 0 THEN
|
||||
OutByte3(0DDH, 5CH + long(n * 8), 24H);
|
||||
OutIntByte(n * 8); (* fstp qword[esp + n*8] *)
|
||||
DEC(fr);
|
||||
INC(n)
|
||||
END;
|
||||
|
||||
IF fr + n > MAX_FR THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
|
||||
WHILE n > 0 DO
|
||||
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
|
||||
addrc(esp, 8);
|
||||
INC(fr);
|
||||
DEC(n)
|
||||
END
|
||||
|
||||
@@ -844,6 +869,12 @@ BEGIN
|
||||
|
||||
ASSERT(R.top = -1);
|
||||
|
||||
IF opcode = IL.opLEAVEF THEN
|
||||
DEC(fr)
|
||||
END;
|
||||
|
||||
ASSERT(fr = -1);
|
||||
|
||||
IF param1 > 0 THEN
|
||||
mov(esp, ebp)
|
||||
END;
|
||||
@@ -1866,15 +1897,25 @@ BEGIN
|
||||
drop
|
||||
|
||||
|IL.opPUSHF:
|
||||
ASSERT(fr >= 0);
|
||||
DEC(fr);
|
||||
subrc(esp, 8);
|
||||
OutByte3(0DDH, 01CH, 024H) (* fstp qword[esp] *)
|
||||
|
||||
|IL.opLOADF:
|
||||
INC(fr);
|
||||
IF fr > MAX_FR THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
UnOp(reg1);
|
||||
OutByte2(0DDH, reg1); (* fld qword[reg1] *)
|
||||
drop
|
||||
|
||||
|IL.opCONSTF:
|
||||
INC(fr);
|
||||
IF fr > MAX_FR THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
float := cmd.float;
|
||||
IF float = 0.0 THEN
|
||||
OutByte2(0D9H, 0EEH) (* fldz *)
|
||||
@@ -1892,35 +1933,55 @@ BEGIN
|
||||
END
|
||||
|
||||
|IL.opSAVEF, IL.opSAVEFI:
|
||||
ASSERT(fr >= 0);
|
||||
DEC(fr);
|
||||
UnOp(reg1);
|
||||
OutByte2(0DDH, 018H + reg1); (* fstp qword[reg1] *)
|
||||
drop
|
||||
|
||||
|IL.opADDF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0C1H) (* faddp st1, st *)
|
||||
|
||||
|IL.opSUBF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0E9H) (* fsubp st1, st *)
|
||||
|
||||
|IL.opSUBFI:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0E1H) (* fsubrp st1, st *)
|
||||
|
||||
|IL.opMULF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0C9H) (* fmulp st1, st *)
|
||||
|
||||
|IL.opDIVF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0F9H) (* fdivp st1, st *)
|
||||
|
||||
|IL.opDIVFI:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr);
|
||||
OutByte2(0DEH, 0F1H) (* fdivrp st1, st *)
|
||||
|
||||
|IL.opUMINF:
|
||||
ASSERT(fr >= 0);
|
||||
OutByte2(0D9H, 0E0H) (* fchs *)
|
||||
|
||||
|IL.opFABS:
|
||||
ASSERT(fr >= 0);
|
||||
OutByte2(0D9H, 0E1H) (* fabs *)
|
||||
|
||||
|IL.opFLT:
|
||||
INC(fr);
|
||||
IF fr > MAX_FR THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
UnOp(reg1);
|
||||
push(reg1);
|
||||
OutByte3(0DBH, 004H, 024H); (* fild dword[esp] *)
|
||||
@@ -1928,6 +1989,8 @@ BEGIN
|
||||
drop
|
||||
|
||||
|IL.opFLOOR:
|
||||
ASSERT(fr >= 0);
|
||||
DEC(fr);
|
||||
subrc(esp, 8);
|
||||
OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 004H); (* fstcw word[esp+4] *)
|
||||
OutByte2(09BH, 0D9H); OutByte3(07CH, 024H, 006H); (* fstcw word[esp+6] *)
|
||||
@@ -1941,18 +2004,24 @@ BEGIN
|
||||
addrc(esp, 4)
|
||||
|
||||
|IL.opEQF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 003H); (* jp L *)
|
||||
setcc(sete, al)
|
||||
(* L: *)
|
||||
|
||||
|IL.opNEF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 003H); (* jp L *)
|
||||
setcc(setne, al)
|
||||
(* L: *)
|
||||
|
||||
|IL.opLTF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 00EH); (* jp L *)
|
||||
setcc(setc, al);
|
||||
@@ -1963,6 +2032,8 @@ BEGIN
|
||||
(* L: *)
|
||||
|
||||
|IL.opGTF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 00FH); (* jp L *)
|
||||
setcc(setc, al);
|
||||
@@ -1973,12 +2044,16 @@ BEGIN
|
||||
(* L: *)
|
||||
|
||||
|IL.opLEF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 003H); (* jp L *)
|
||||
setcc(setnc, al)
|
||||
(* L: *)
|
||||
|
||||
|IL.opGEF:
|
||||
ASSERT(fr >= 1);
|
||||
DEC(fr, 2);
|
||||
fcmp;
|
||||
OutByte2(07AH, 010H); (* jp L *)
|
||||
setcc(setc, al);
|
||||
@@ -1990,6 +2065,10 @@ BEGIN
|
||||
(* L: *)
|
||||
|
||||
|IL.opINF:
|
||||
INC(fr);
|
||||
IF fr > MAX_FR THEN
|
||||
ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR)
|
||||
END;
|
||||
pushc(7FF00000H);
|
||||
pushc(0);
|
||||
OutByte3(0DDH, 004H, 024H); (* fld qword[esp] *)
|
||||
@@ -2126,8 +2205,8 @@ BEGIN
|
||||
END;
|
||||
|
||||
ASSERT(R.pushed = 0);
|
||||
ASSERT(R.top = -1)
|
||||
|
||||
ASSERT(R.top = -1);
|
||||
ASSERT(fr = -1)
|
||||
END translate;
|
||||
|
||||
|
||||
@@ -2296,6 +2375,7 @@ VAR
|
||||
opt: PROG.OPTIONS;
|
||||
|
||||
BEGIN
|
||||
FR[0] := 0;
|
||||
tcount := CHL.Length(IL.codes.types);
|
||||
|
||||
opt := options;
|
||||
|
||||
Reference in new issue
Block a user