drkr
drkr

Reputation: 456

ARM GCC compiler "buggy" conversion

Problem

I am working with flash memory optimization of STM32F051. It's revealed, that conversion between floatand int types consumes a lot of flash.

Digging into this, it turned out that the conversion to int takes around 200 bytes of flash memory; while the conversion to unsigned int takes around 1500 bytes!

It’s known, that both int and unsigned int differ only by the interpretation of the ‘sign’ bit, so such behavior – is a great mystery for me.

Note: Performing the 2-stage conversion float -> int -> unsigned int also consumes only around 200 bytes.

Questions

Analyzing that, I have such questions:

1) What is a mechanism of the conversion of float to unsigned int. Why it takes so many memory space, when in the same time conversion float->int->unsigned int takes so little memory? Maybe it’s connected with IEEE 754 standard?

2) Are there any problems expected when the conversion float->int->unsigned int is used instead of a direct float ->int?

3) Are there any methods to wrap float -> unsigned int conversion keeping the low memory footprint?

Note: The familiar question has been already asked here (Trying to understand how the casting/conversion is done by compiler,e.g., when cast from float to int), but still there is no clear answer and my question is about the memory usage.


Technical data

Code example

  1. float -> int (~200 bytes of flash)

    int main() {
    volatile float f;
    volatile int i;
    i = f;
    return 0;
    }
    
  2. float -> unsigned int (~1500 bytes! of flash)

    int main() {
    volatile float f;
    volatile unsigned int ui;
    ui = f;
    return 0;
    }
    
  3. float ->int-> unsigned int (~200 bytes of flash)

    int main() {
    volatile float f;
    volatile int i;
    volatile unsigned int ui;
    i = f;    
    ui = i;
    return 0;
    }
    

Upvotes: 2

Views: 287

Answers (1)

Johan
Johan

Reputation: 3891

There is no fundamental reason for the conversion from float to unsigned int should be larger than the conversion from float to signed int, in practice the float to unsigned int conversion can be made smaller than the float to signed int conversion.

I did some investigations using the GNU Arm Embedded Toolchain (Version 7-2018-q2) and as far as I can see the size problem is due to a flaw in the gcc runtime library. For some reason this library does not provide an specialized version of the __aeabi_f2uiz function for Arm V6m, instead it falls back on a much larger general version.

Upvotes: 1

Related Questions