MOVW/MOVT versus LDRs from a literal pool

Asked by Tamas Kleiber

Hi,

 I am porting my project from Sourcery CodeBench 2012-09-63 (GCC 4.7.2) to GNU Tools for ARM Embedded Processors 4.7-2013-q3-update 2013-09-26 (GCC 4.7.4).

My project runs on a Cortex-M3 r2p1 CPU core based MCU. I found that in the GCC ARM Embedded compiler base_address->member_x like constructs emit MOVW/MOVT pairs to load base_address to a register while Sourcery CodeBench moves base_address to a literal pool and loads the address to a register using the LDR instruction.

Example assembler listing (MOVW/MOVT):

  4FF6D073 movw r3, #65488
  CEF20F03 movt r3, 57359
  1B69 ldr r3, [r3, #16]

Example assmebler listing (LDR with literal pool):

  104B ldr r3, .L23
  1B69 ldr r3, [r3, #16]

  .L23:
  D0FF0FE0 .word -535822384

The resulting executable / binary size difference from this is considerable. I know that LDR is slow compared to MOVW/MOVT but my project has sever ROM size constraints and I cannot allow my self to loose any more ROM space.

I have seen a bug report at the Linaro GCC project: https://bugs.launchpad.net/gcc-linaro/+bug/886124 where the same topic is discussed from their perspective, but they favor speed over anything else so ...

Is there a way to tell the compiler to favor LDRs from liter pools instead of MOVW/MOVT pairs? Is there a configuration setting or something to control this behavior?

Thank you in advance for your kind response.

Best regards,
 Tamas

_

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Terry Guo
Solved:
Last query:
Last reply:
Revision history for this message
Best Terry Guo (terry.guo) said :
#1

How about compiling your project with -Os option? I think the LDR will be used then.

Revision history for this message
Joey Ye (jinyun-ye) said :
#2

Tamas,

We have a patch on the way to solve it in GCC mainline and next GCC release. So far can you please try -Os as Terry suggested?

Thanks,
Joey

Revision history for this message
Tamas Kleiber (kleiber-tamas) said :
#3

Dear Terry and Joey,

 thanks for the quick response and the info about the patch, this sounds pretty good.

-Os does change the behavior which is nice, but most unfortunately I face the issue that my application does not fit into the MCU's ROM space anymore with -O0 or -O1 due to the additional 1.5k ROM size required by MOVW/MOVT in these modes. Thus, I cannot really create a debug build anymore which would allow me to debug C level code "conveniently".

I will try to figure out which optimizer flags the -Os option switches on using gcc -Q --help=optimizers. Maybe there is a flag which I can explicitly enable and still use -O0 or -O1 or the likes.

Thank again for the quick response.

Revision history for this message
Terry Guo (terry.guo) said :
#4

I just checked the gcc source code and don't think there is a dedicated flag for this purpose. GCC simply disable the MOVW/MOVT when it isn't -Os. Here is the GCC code:

#define TARGET_USE_MOVT \
  (arm_arch_thumb2 && !optimize_size && !current_tune->prefer_constant_pool)

Revision history for this message
Tamas Kleiber (kleiber-tamas) said :
#5

Well,

 I found no explicit option other than -Os so I will work around the issue by removing logging and tracing features from the application whenever I have to debug the application and I will use -Os in release builds.

Joey,

 do you know by chance whether the GCC mainline patch that you have mentioned will be available only for GCC 4.8.x or will it be available also for GCC 4.7.x?

Best regards,
 Tamas

Revision history for this message
Terry Guo (terry.guo) said :
#6

Sorry it should read as "GCC simply disable the MOVW/MOVT when it is -Os".

Revision history for this message
Tamas Kleiber (kleiber-tamas) said :
#7

Thanks Terry Guo, that solved my question.

Revision history for this message
Terry Guo (terry.guo) said :
#8

In terms of reducing the code size, have you tried the options like "-ffunction-sections, -fdata-sections, -Wl,--gc-sections"?

Revision history for this message
Tamas Kleiber (kleiber-tamas) said :
#9

Hi Terry,

 thanks for looking up the source code and to answer your last question, I am using the garbage collection options already. I will find a workaround for debugging and for release builds I could use -O2/3 or -Os still.

Or maybe based on the source code snippet which you provided I could try to build the compiler from sources. We will see :)

Thanks again for all your efforts!