lto complains that "error: r7 cannot be used in asm here"

Bug #1379236 reported by Terry Guo
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Invalid
Undecided
Terry Guo

Bug Description

Building attached project with option -flto leads to below errors:

rtos/rtx/rt_CMSIS.c: In function 'osThreadCreate':
rtos/rtx/rt_CMSIS.c:689:1: error: r7 cannot be used in asm here
 }
 ^
lto-wrapper: arm-none-eabi-gcc returned 1 exit status
/usr/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld: lto-wrapper failed
collect2: error: ld returned 1 exit status
make: *** [usr_prj.elf] Error 1

The GCC version is:
terguo01@terry-pc01:usr_prj$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Revision history for this message
Terry Guo (terry.guo) wrote :
Changed in gcc-arm-embedded:
status: New → Confirmed
assignee: nobody → Terry Guo (terry.guo)
Revision history for this message
Terry Guo (terry.guo) wrote :

This bug is caused by using r7 register through below inline assembly code in file rtx/rt_CMSIS.c:

#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS)
#define SVC_Call(f) \
  __asm volatile \
  ( \
    "ldr r7,="#f"\n\t" \
    "mov r12,r7\n\t" \
    "svc 0" \
    : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \
    : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \
    : "r7", "r12", "lr", "cc" \
  );
#else

The r7 is used as frame pointer register for thumb1 target cortex-m0. It is not allowed to be changed like above ldr instruction when the frame register is actually needed.

Above inline assembly code is used in below function:

// Thread Public API

/// Create a thread and add it to Active Threads and set it to state READY
osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) {
  if (__get_IPSR() != 0) return NULL; // Not allowed in ISR
  if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
    // Privileged and not running
    return svcThreadCreate(thread_def, argument);
  } else {
    return __svcThreadCreate(thread_def, argument);
  }
}

When lto is disabled, this function is pretty simple and won't use stack, so frame pointer register isn't going to be needed. Everything is fine. It's allowed to use r7 as above ldr instruction.

When lto is enabled, the function svcThreadCreate will be inlined into function osThreadCreate by lto. The stack will be used and then the frame pointer register will be used for accessing stack like [r7, #4]. It's not allowed to change r7 now like above ldr instruction. The error message is generated. This makes sense.

I think the correct way to avoid such error is avoiding use r7 in this inline assembly code.

A workaround is to use option -fomit-frame-pointer, but it will lead to another bug which I am looking into.

Changed in gcc-arm-embedded:
status: Confirmed → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.