Prev: ATI Catalyst 10.3 Preview Edition
Next: Network fabric
From: linnix on 19 Mar 2010 16:59 On Mar 19, 1:52 pm, Tauno Voipio <tauno.voi...(a)notused.fi.invalid> wrote: > On 18.3.10 7:47 , linnix wrote: > > > > > In response to another thread, I am still getting these problems with > > WinAVR 2010. I think the linker is hitting some AVR limits. There > > are similar reports on the web as well. > > ------------------------------------------------------------------------------------------------- > > > unsigned char u; > > float f; > > > u = (unsigned char) f; > > > --------------------------------------------------------------------------------------------------- > > c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/ > > avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd': > > (.text.avr-libc.fplib+0x10): relocation truncated to fit: > > R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in > > c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o) > > c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/ > > avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd': > > (.text.avr-libc.fplib+0x20): relocation truncated to fit: > > R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in > > c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o) > > Did you use the proper -mmcu= option on the GCC command line? Yes, -mmcu=atmega32u2 > > The errors point thet the compiler has generated code for > 13 bit addresses (8 kiB memory), and the code exceeds the > 13 bit address range. That's why its confusing. Non-existence is also out of range. I can get around it with including the source or binary for the fp_powodd function. > > -- > > Tauno Voipio > tauno voipio (at) iki fi
From: Grant Edwards on 19 Mar 2010 23:48 On 2010-03-19, Habib Bouaziz-Viallet <h.bouazizviallet(a)free.fr> wrote: >> gcc does not promote the "(unsigned char) f" to an int - it would only >> do that if you were doing maths on the value. > That is exactly the point. Why in the earth someone would need to > convert a float (doing sine and cosine) to a unsigned char ??? Presumably because 1) they know the result will be within the range 0-255, and 2) the AVR is an 8-bit CPU, and operating on 8-bit integer values is a _lot_ faster than operating on 16-bit or 32-bit integer values. > I said that extracting the integer part of the float is ok when > casting a float to an int. That's what the OP was doing: casting the float to an 8-bit unsigned integer. > When you make a cast from a float to an unsigned int it would result > a zero if the float is negative (not quite sure either ... just > conjecture) No, that's not how it works. > BTW i don't know what would be the result if the target has a FPU > (like our big bunch desktop machines) ... :-) The result would be the same. -- Grant
From: Habib Bouaziz-Viallet on 20 Mar 2010 06:49 Grant Edwards wrote: > On 2010-03-19, Habib Bouaziz-Viallet <h.bouazizviallet(a)free.fr> wrote: > >>> gcc does not promote the "(unsigned char) f" to an int - it would only >>> do that if you were doing maths on the value. > >> That is exactly the point. Why in the earth someone would need to >> convert a float (doing sine and cosine) to a unsigned char ??? > > Presumably because 1) they know the result will be within the range > 0-255, and 2) the AVR is an 8-bit CPU, and operating on 8-bit integer > values is a _lot_ faster than operating on 16-bit or 32-bit integer > values. > >> I said that extracting the integer part of the float is ok when >> casting a float to an int. > > That's what the OP was doing: casting the float to an 8-bit unsigned > integer. > >> When you make a cast from a float to an unsigned int it would result >> a zero if the float is negative (not quite sure either ... just >> conjecture) > > No, that's not how it works. No ? Please compile this (gcc -o test -c test -lm) and tell me what you see. #include <stdio.h> #include <stdlib.h> #include <math.h> #define PI 3.14 int main(void) { float value=0; while(value<10) { printf("%f\n", 10*sinf(2*PI*value)); printf("%d\n\n", (unsigned char)(10*sinf(2*PI*value)) ); value+=0.1; } return(EXIT_SUCCESS); } I knew this was not a related compiler issue or what else (on this i agree with David), finally i give up because this thread is a serie of non-sense. > >> BTW i don't know what would be the result if the target has a FPU >> (like our big bunch desktop machines) ... :-) > > The result would be the same. > Habib
From: David Brown on 20 Mar 2010 07:11 linnix wrote: > On Mar 19, 1:52 pm, Tauno Voipio <tauno.voi...(a)notused.fi.invalid> > wrote: >> On 18.3.10 7:47 , linnix wrote: >> >> >> >>> In response to another thread, I am still getting these problems with >>> WinAVR 2010. I think the linker is hitting some AVR limits. There >>> are similar reports on the web as well. >>> ------------------------------------------------------------------------------------------------- >>> unsigned char u; >>> float f; >>> u = (unsigned char) f; >>> --------------------------------------------------------------------------------------------------- >>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/ >>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd': >>> (.text.avr-libc.fplib+0x10): relocation truncated to fit: >>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in >>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o) >>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/ >>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd': >>> (.text.avr-libc.fplib+0x20): relocation truncated to fit: >>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in >>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o) >> Did you use the proper -mmcu= option on the GCC command line? > > Yes, -mmcu=atmega32u2 > >> The errors point thet the compiler has generated code for >> 13 bit addresses (8 kiB memory), and the code exceeds the >> 13 bit address range. > > That's why its confusing. Non-existence is also out of range. > > I can get around it with including the source or binary for the > fp_powodd function. > As you have said yourself, it sounds like this could be an issue with the linker setup for this particular chip - it's nothing to do with the compiler as such. But you will get far more helpful answers from the avr-gcc mailing list - there is no need for workarounds like this until you have confirmed that it is a bug and not something else. If it /is/ a bug in the linker setup, then the avr-gcc team would very much like to hear about it - that way it can be fixed for everyone. And if a workaround of some sort is needed, then there may be better or more convenient alternatives - your fix here may be relying on the luck of the link order, and you could get the same problem later with something else. Other possibilities are to use different -mmcu flags for compilation and linking - use "-mmcu=atmega32u2" during compilation (that ensures you get the right IO headers, etc.), and a different 32K micro when linking (to work around this possible bug in the atmega32u2 link setup). I've done similar things in the past to work with devices that were not yet supported.
From: Jamie on 20 Mar 2010 11:25
Cesar Rabak wrote: > Em 18/3/2010 17:39, linnix escreveu: > >> On Mar 18, 11:21 am, Habib Bouaziz-Viallet<h.bouazizvial...(a)free.fr> >> wrote: >> >>> Le Thu, 18 Mar 2010 10:47:44 -0700, linnix a �crit : >>> >>>> unsigned char u; >>>> float f; >>> >>> >>>> u = (unsigned char) f; >>> >>> >>> In what kind of situation you need to cast a float to that unsigned >>> char ??? >>> If you want to extract the integer part of the float, let me tell you >>> that this way is a bit silly. >>> >>> Question yourself before asking to C. >>> >>> Habib >> >> >> f is result of k1 * sine x + k2 * cosine y. >> >> How would you extract the integer part without casting? > > > I would use round(), trunc(), ceil() or floor() as each could better fit. > Every C compiler I've seen does not require a cast to get the integer part of a float. The compile just generates magical code in the background for it myinteger = myfloat; Or course, this implies that the C compiler is loading it's default RTL so that it knows how to handle floats, since AVR's to my knowledge, do not have float operations in the cpu..(FPU) etc.. |