#31 Floating point constants are coded as 0.0 Edit

v1.3.0
open
nobody
None
1
2014-02-01
2014-01-03
No

Using AVR-Ada v1.2.2 (gcc 4.7.2), almost all the floating point computations fails. Which is awkward, as my project (EQ Track) relies on floating point matrices to orient a telescope.
After a bit of investigation, it turns out that floating points constants are treated as 0.0, as illustrated below :

The code sample float_test.adb (cf. attached file), when compiled with the command

avr-gcc -c -g -Os -mmcu=at90usb1287 --RTS=rts/avr51 -gnatp ../test/float_test.adb -Wa,-adhlns=float_test_ada.lst

generates the following assembly code (cf. attached file float_test_ada.lst) :

11:../test/float_test.adb ****       P1: Interfaces.IEEE_Float_32 := Interfaces.IEEE_Float_32(R)/Max_Remainder;
...
71 002a 20E0            ldi r18,0
72 002c 30E0            ldi r19,0
73 002e A901            movw r20,r18
74 0030 0E94 0000       call __divsf3

Max_Remainder (equal to 4096) is set into r18 .. r21 as 0x00000000, or 0.0.
In the following source line, the operation "1.0 - P1" is coded as "0.0 - P1".

The same code translated in C (cf. attached file float_test.c), when compiled with the command

avr-gcc -c -g -Os -mmcu=at90usb1287 ../test/float_test.c -Wa,-adhlns=float_test_c.lst

 8:../test/float_test.c ****    float P1 = (float)R/Max_Remainder;
...
58 0026 20E0            ldi r18,0
59 0028 30E0            ldi r19,0
60 002a 40E8            ldi r20,lo8(-128)
61 002c 59E3            ldi r21,lo8(57)
62 002e 0E94 0000       call __mulsf3

Here the generated code is a multiplication with 0x39800000, or 2**-12 ; hence a division by 4096. This is correct, and the "1.0 - P1" operation is also coded correctly.

A native compilation is also correct, the problem seems therefore specific to Ada on AVR ; but that precisely the language and target of my application...
This bug was not present in AVR 1.20 (gcc 4.5).

6 Attachments

Discussion

  • Rolf Ebert
    Rolf Ebert
    2014-01-13

    I have never tried floating point maths on AVR, so no experience whatsoever. I share your opinion that it is a frontend problem for the AVR target . there are only a few remarks about your code:

    • Are you sure that the remainder runs from 0 to 4096, not 4095?
    • did you try with standard Float instead of IEEE_Float?
    • why do you pass the interpolation table as an access? a standard in parameter would be equally fine
     


Anonymous


Cancel   Add attachments