исправлена ошибка в работе с вещественными регистрами
This commit is contained in:
AntKrotov committed 2020-08-26 21:46:37 +03:00
1 parent e663c9ee33
commit 1df858a3b9
9 files changed
+231 -184

No files matched your search

-1
View File
@@ -1 +0,0 @@
*.exe
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+56 -11
View File
@@ -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
View File
@@ -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;
+4
View File
@@ -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
View File
@@ -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
View File
@@ -25,7 +25,7 @@ CONST
max32* = 2147483647;
vMajor* = 1;
vMinor* = 35;
vMinor* = 36;
FILE_EXT* = ".ob07";
RTL_NAME* = "RTL";
+91 -11
View File
@@ -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;