[Oberon] On a code generated for Math.Mod.txt

Jörg joerg.straube at iaeth.ch
Fri Jul 15 12:37:38 CEST 2016


Hi Srinivas

In Oberon-2 we had LONGINT and INTEGER. The compiler implemented these with 32 and 16 bit.
In Oberon-07 only INTEGER is defined. The compiler implements INTEGER with 32 bit.
For compatibility reasons (being able to reuse old Oberon-2 code) the compiler in ProjectOberon defines LONGINT = INTEGER;

Being able to use SYSTEM.VAL(T, x) the type T and the type of x have to have the same size.
It only converts the type, it does not convert the value. The bits stay exactly the same.
(BTW: a little bit comparable to union{} in C)

SYSTEM.VAL(LONGINT, realval) can be written in Oberon-2 and Oberon-07
SYSTEM.VAL(INTEGER, realval) only works in Oberon-07

br
Jörg

-----Original Message-----
From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of Srinivas Nayak
Sent: Freitag, 15. Juli 2016 10:37
To: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Subject: Re: [Oberon] On a code generated for Math.Mod.txt

Thanks Jorg,

Nice step taken.

I think we are going to keep only INTEGER and deprecate LONGINT...right?
Or?

And, will not SYSTEM.VAL() cause any rounding error using it several times
from LONGINT to REAL and REAL to LONGINT ?

I am not sure on these. Just a thought.
You can better judge here.



With thanks and best regards,

Yours sincerely,
Srinivas Nayak

Home: http://www.mathmeth.com/sn/
Blog: http://srinivas-nayak.blogspot.in/

On 07/15/2016 12:38 PM, Joerg wrote:
> Hi Srinivas
>
> While investigating your problem I found two flaws in the current compiler :-(
>
> Lets start with the basics
> The rounding effect you found in the C compiler has the Oberon compiler as well. At least in the emulator, did not check on the real  FPGA implementation yet.
>
> Compile this code, and look at the assembly
> - - - - - -
>    MODULE RealTest
>    VAR r1, r2: REAL
>    BEGIN
>      r1 := 0.99999993;
>      r2 := 0.99999994;
>    END RealTest.
> - - - - - -
> You will find that r1 is smaller than 1.0 and r2 is equal to 1.0.
>
> So the rounding effect is there, but it is numerically incorrect, as the rounding effect should occur between
>    0.99999998 and 0.99999999
> This is the first flaw: The code in ORS.Number is not fine-tuned to numerical rounding errors when dealing with REALs.
>
> I wanted to prove my statement that it is possible to improve the compiler code by doing this:
>    MODULE RealTest
>    VAR r1, r2: REAL
>    BEGIN
>      r1 := 0.9999999 + 8.E-8;
>      r2 := 0.9999999 + 9.E-8;
>    END RealTest.
>
> By compiling this, I found that the compiler does not evaluate constant expressions when dealing with REAL constants
> (Unnecessary FADDs are generated)
>
> Hence I added the const evaluation to ORG.RealOp to
>
> 	PROCEDURE RealOp*(op: INTEGER; VAR x, y: Item);	(* x := x op y *)
> 	BEGIN
> 		IF (x.mode = ORB.Const) & (y.mode = ORB.Const) THEN
> 			IF op = ORS.plus THEN x.a := S.VAL(LONGINT, S.VAL(REAL, x.a) + S.VAL(REAL, y.a))
> 			ELSIF op = ORS.minus THEN x.a := S.VAL(LONGINT, S.VAL(REAL, x.a) - S.VAL(REAL, y.a))
> 			ELSIF op = ORS.times THEN x.a := S.VAL(LONGINT, S.VAL(REAL, x.a) * S.VAL(REAL, y.a))
> 			ELSIF op = ORS.rdiv THEN
> 				IF S.VAL(SET, y.a) - {31} = {}  THEN (* catching IEEE754 +0 and -0 *)
> 					ORS.Mark(„divisor 0.0“)
> 				ELSE
> 					x.a := S.VAL(LONGINT, S.VAL(REAL, x.a) / S.VAL(REAL, y.a))
> 				END
> 			END
> 		ELSE
> 			load(x); load(y);
> 			IF op = ORS.plus THEN Put0(Fad, RH-2, x.r, y.r)
> 			ELSIF op = ORS.minus THEN Put0(Fsb, RH-2, x.r, y.r)
> 			ELSIF op = ORS.times THEN Put0(Fml, RH-2, x.r, y.r)
> 			ELSIF op = ORS.rdiv THEN Put0(Fdv, RH-2, x.r, y.r)
> 			END ;
> 			DEC(RH); x.r := RH-1
> 		END
> 	END RealOp;
>
> After compiling ORG.Mod, unloading the old compiler and re-compiling my test module with the improved compiler, you see that r1 is smaller than 1.0 and r2 is 1.0 —> the rounding effect is indeed between  0.99999998 and 0.99999999.
>
> Jörg
>
>> Am 14.07.2016 um 09:25 schrieb Srinivas Nayak <sinu.nayak2001 at gmail.com>:
>>
>> Thanks Jorg.
>> You are correct.
>>
>> I see in C, on x86,
>>
>> #include <stdio.h>
>> int main()
>> {
>> 	union {float f; int i;}u;
>>
>> 	u.f = 9.999999e-1;
>> 	printf("%e  =  ", u.f);
>> 	printf("%#x\n", u.i);
>>
>> 	u.f = 9.9999999e-1;
>> 	printf("%e  =  ", u.f);
>> 	printf("%#x\n", u.i);
>>
>> 	return 0;
>> }
>>
>> produces
>>
>> # ./a.out
>> 9.999999e-01  =  0x3f7ffffe
>> 1.000000e+00  =  0x3f800000
>> #
>>
>> But I think, Oberon doesn't convert 9.9999999e-1 to 1.000000e+00.
>> When both use 32bit and use IEEE 754 format, what is causing this?
>> Is it language trick? I don't think so, since Oberon compiler doesn't do anything special for this.
>> Is it processor dependent thing? Don't know anything about this.
>>
>> Hope you will shed some more light on this deepening darkness.
>>
>>
>>
>> With thanks and best regards,
>>
>> Yours sincerely,
>> Srinivas Nayak
>>
>> Home: http://www.mathmeth.com/sn/
>> Blog: http://srinivas-nayak.blogspot.in/
>>
>> On 07/14/2016 03:26 AM, Jörg Straube wrote:
>>> Srinivas
>>>
>>>     MOV' R1 #aa    (upper 16 bit)
>>>     IOR R1 #bb       (lower 16 bit)
>>> is the code to fill the register R1 with the 32 bit constant #aabb
>>>
>>> You find all the details of the RISC5 instruction set in this paper:
>>> https://www.inf.ethz.ch/personal/wirth/FPGA-relatedWork/RISC-Arch.pdf
>>>
>>> Jörg
>>>
>>>
>>>
>>> Gruss, Jörg
>>>> Am 13.07.2016 um 21:18 schrieb Srinivas Nayak <sinu.nayak2001 at gmail.com>:
>>>>
>>>> In math.Mod.txt we see
>>>>
>>>> q0 =  9.9999999E-1;
>>>> IF ODD(n) THEN f := (((((q6*yy + q5)*yy + q4)*yy + q3)*yy + q2)*yy + q1)*yy + q0
>>>>
>>>> ELSE
>>>>
>>>> For the last addition of q0, I see the code generated is:
>>>>
>>>> 61003F7F  MOV'  R1  R0  16255
>>>>
>>>> 4116FFFE  IOR  R1  R1     -2
>>>>
>>>> How it is different from
>>>>
>>>> 61003F80  MOV'  R1  R0  16256
>>>>
>>>>
>>>>
>>>>
>>>> With thanks and best regards,
>>>>
>>>> Yours sincerely,
>>>> Srinivas Nayak
>>>>
>>>> Home: http://www.mathmeth.com/sn/
>>>> Blog: http://srinivas-nayak.blogspot.in/
>>>> --
>>>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>>>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>>
>>> --
>>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>>
>> --
>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>
--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon



More information about the Oberon mailing list