6
\$\begingroup\$

I have set the -mshort-calls flag which is documented to replace the 4 byte long CALL instruction with the 2 byte long RCALL instruction when possible to save flash space and and cycles...

-mshort-calls

Assume that RJMP and RCALL can target the whole program memory.

This option is used internally for multilib selection. It is not an optimization option, and you don’t need to set it by hand.

https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html#index-mshort-calls

...and it set in Atmel Studio here...

enter image description here

Unfortunately the compiler is still using full CALL instructions even for a call that is only 2 bytes away...

    ...
    35f6:   0e 94 fd 1a     call    0x35fa  ; 0x35fa         
    35fa:   f8 94           cli
    ...

What am I doing wrong?

\$\endgroup\$
8
\$\begingroup\$

This option was removed in gcc 4.8 but not all the documentation was updated. Atmel Studio also still uses the obsolete flag.

The new option is called -mrelax on the compiler command line or --relax on the linker command line...

https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/AVR-Options.html

After adding that flag, the above code compiled to...

...
3584:   00 d0           rcall   .+0         ; 0x3586 
3586:   f8 94           cli
...

If you are using Atmel Studio, the new flag is misleadingly called "Relax Branches" and is located here...

enter image description here

In my case, enabling relative jumps and calls resulted in significant flash savings. If you are here because you also need to save flash space and/or cycles, I'd also recommend looking into enabling Link Time Optimization which also offers great savings at no cost.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.