[Oberon] On a code generated for Math.Mod.txt
Joerg
joerg.straube at iaeth.ch
Fri Jul 15 09:08:59 CEST 2016
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
More information about the Oberon
mailing list