issue-#207 Compiler TRAPs with simple CONST expression

User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

issue-#207 Compiler TRAPs with simple CONST expression

Post by Robert »

User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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.
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post by Josef Templ »

I will look at luowy's fix in the next few days.

- Josef
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
luowy
Posts: 234
Joined: Mon Oct 20, 2014 12:52 pm

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
luowy
Posts: 234
Joined: Mon Oct 20, 2014 12:52 pm

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
luowy
Posts: 234
Joined: Mon Oct 20, 2014 12:52 pm

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post by luowy »

my typo problem:
I checked code with

Code: Select all

DevCPL486.MakeConst(c, 1, Bool); 

it should be

Code: Select all

DevCPL486.MakeConst(x, 1, Bool); 
as you provided;

I agree with your code!

luowy
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#207 Compiler TRAPs with simple CONST expression

Post 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
Post Reply