Page 1 of 2
issue-#207 Compiler TRAPs with simple CONST expression
Posted: Fri Jun 05, 2020 5:13 pm
by Robert
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Fri Jun 05, 2020 5:17 pm
by Robert
I have tried the suggested fix, and it stops the compiler TRAPing, and appears to work correctly.
I have done only a very few tests, and don't claim to understand how the code works.
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Fri Jun 05, 2020 6:33 pm
by Josef Templ
I will look at luowy's fix in the next few days.
- Josef
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sat Jun 06, 2020 7:14 am
by Josef Templ
@luowy
It would actually be sufficient to convert the conditional expression into a boolean constant for such cases, I think.
As a side effect, it produces more compact code, however, in such exotic cases this is a minor point.
My tests are successful, at least.
DevCPC486.LoadCond
Code: Select all
IF y.offset >= 0 THEN DevCPL486.GenSetCC(y.offset, x)
ELSIF y.offset = ccAlways THEN DevCPL486.MakeConst(x, 1, Bool)
ELSIF y.offset = ccNever THEN DevCPL486.MakeConst(x, 0, Bool)
ELSE HALT(100)
END
What do you think?
- Josef
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sat Jun 06, 2020 12:58 pm
by luowy
Josef Templ wrote:DevCPC486.LoadCond
CODE: SELECT ALL
IF y.offset >= 0 THEN DevCPL486.GenSetCC(y.offset, x)
ELSIF y.offset = ccAlways THEN DevCPL486.MakeConst(x, 1, Bool)
ELSIF y.offset = ccNever THEN DevCPL486.MakeConst(x, 0, Bool)
ELSE HALT(100)
END
What do you think?
ooh, it's not ok,
but it will be ok if re-add the statement "DevCPL486.GenMove(c, x);"
Code: Select all
IF y.offset >= 0 THEN DevCPL486.GenSetCC(y.offset, x)
ELSIF y.offset = ccAlways THEN DevCPL486.MakeConst(x, 1, Bool);DevCPL486.GenMove(c, x);
ELSIF y.offset = ccNever THEN DevCPL486.MakeConst(x, 0, Bool);DevCPL486.GenMove(c, x);
ELSE HALT(100)
END
I prefer the code aboveļ¼
the difference between them can be checked by decoding the distilled module provided by Chris easily;
or my test module
Code: Select all
MODULE ObxConstTest1;
PROCEDURE Do();
CONST
f = FALSE;
VAR
b,a: BOOLEAN;
BEGIN
b := (b OR ~f) & f; (*trap*)
b := (b & f) OR ~f; (*trap*)
IF (b OR ~f) & f THEN a:=TRUE;END; (*no trap*)
IF (b & f) OR ~f THEN a:=TRUE; END; (*no trap *)
(*b := a =FALSE; *) (* setcc *)
END Do;
END ObxConstTest1.
luowy
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sat Jun 06, 2020 5:52 pm
by Josef Templ
@luowy,
there is no trap in my solution either.
There is a subtle detail with a missing Free(x), though. I mean, there is a register allocated at the beginning but in my proposal there is no Free(x) before changing x into a constant.
Please check.
The difference is that I am returning a Con item, not a Reg item.
The expr that calls LoadCond and the assignment that follows can deal with any item mode.
- Josef
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sun Jun 07, 2020 2:49 am
by luowy
let's check the decoding of this statement :
Code: Select all
CONST f = FALSE;
VAR b: BOOLEAN;
b := (b OR ~f) & f; (* b == FALSE *)
with "DevCPL486.GenMove(c, x);"
Code: Select all
63190037: 80 7D FF 00 CMP BYTE [EBP-1], 0
6319003B: 0F 85 00 00 00 00 JNZ 0 (63190041H)
63190041: 30 C0 XOR AL, AL
63190043: 88 45 FF MOV [EBP-1], AL
wihout "DevCPL486.GenMove(c, x);"
Code: Select all
66220037: 80 7D FF 00 CMP BYTE [EBP-1], 0
6622003B: 0F 85 00 00 00 00 JNZ 0 (66220041H)
66220041: 88 45 FF MOV [EBP-1], AL
Obviously, the second one lack "XOR AL, AL"; will give a radom resoult, it's wrong;
the reason is: at backend (the last pass of compiler), Con(st) Item will no longer be automatically converted to code.
luowy
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sun Jun 07, 2020 8:36 am
by Josef Templ
@luowy
here is the decoding I get from your example:
Code: Select all
00000001H: 55 push ebp
00000002H: 8B EC mov ebp, esp
00000004H: 83 C4 FC add esp, -4
b := (b OR ~f) & f; (*trap*)
00000007H: 80 7D FF 00 cmp -1[ebp], 0
0000000BH: 0F 85 00 00 00 00 jnz 0 (00000011H)
00000011H: C6 45 FF 00 mov -1[ebp], 0
b := (b & f) OR ~f; (*trap*)
IF
00000015H: 80 7D FF 00 cmp -1[ebp], 0
00000019H: 0F 84 00 00 00 00 jz 0 (0000001FH)
0000001FH: C6 45 FF 01 mov -1[ebp], 1
(b OR ~f) & f THEN
00000023H: 80 7D FF 00 cmp -1[ebp], 0
00000027H: 0F 85 00 00 00 00 jnz 0 (0000002DH)
0000002DH: E9 04 00 00 00 jmp 4 (00000036H)
a:=TRUE;END; (*no trap*)
IF
00000032H: C6 45 FE 01 mov -2[ebp], 1
(b & f) OR ~f THEN
00000036H: 80 7D FF 00 cmp -1[ebp], 0
0000003AH: 0F 84 00 00 00 00 jz 0 (00000040H)
a:=TRUE; END; (*no trap *)
(*b := a =FALSE; *) (* setcc *)
00000040H: C6 45 FE 01 mov -2[ebp], 1
00000044H: 8B E5 mov esp, ebp
00000046H: 5D pop ebp
00000047H: C3 ret
I cannot see any error.
If you get a different result, there must be something wrong in your test setup, I think.
Maybe you have not copied my solution literally but exchanged x for c in DevCPL486.MakeConst(x, 1, Bool) ?
Here is my latest version that also includes a Free(x).
Code: Select all
IF y.offset >= 0 THEN DevCPL486.GenSetCC(y.offset, x)
ELSIF y.offset = ccAlways THEN Free(x); DevCPL486.MakeConst(x, 1, Bool)
ELSIF y.offset = ccNever THEN Free(x); DevCPL486.MakeConst(x, 0, Bool)
ELSE HALT(100)
END
- Josef
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sun Jun 07, 2020 10:41 am
by luowy
my typo problem:
I checked code with
it should be
as you provided;
I agree with your code!
luowy
Re: issue-#207 Compiler TRAPs with simple CONST expression
Posted: Sun Jun 07, 2020 6:24 pm
by Josef Templ
@luowy,
thanks for he info that we are in sync now.
There is one more subtle detail to look at:
It is the line marked <--- below.
I don't know what a1 and a2 are used for and if that is of any relevance for our cases.
It seems to be of relevance in case a comparison operation is converted into a boolean value (GenSetCC is used for that)
but what if it is also relevant for ccAlways and ccNever?
Code: Select all
PROCEDURE GenSetCC* (cc: INTEGER; VAR dst: Item);
BEGIN
ASSERT((dst.form = Bool) & (cc >= 0));
DevCPE.GenByte(0FH); DevCPE.GenByte(90H + cc); GenCExt(0, dst);
IF (dst.mode # Reg) OR (dst.reg = AX) THEN a1.mode := 0; a2.mode := 0 END <---
END GenSetCC;
- Josef