writing to a specific register in a c++ template function results in wrong assembler code

Bug #1658362 reported by Daniel Böhmer
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
New
Undecided
Unassigned

Bug Description

The following function

__attribute__((always_inline))
static inline void storeR12normally()
{
   register uint32_t r asm("r12");
   r = (uint32_t)testFunc;
   asm volatile ("svc 0" : : "r"(r) : "r0","r1");
}

results in the following assembly:

   register uint32_t r asm("r12");
   r = (uint32_t)testFunc;
 8000368: 4b04 ldr r3, [pc, #16] ; (800037c <main+0x18>)
 800036a: 469c mov ip, r3
   asm volatile ("svc 0" : : "r"(r) : "r0","r1");
 800036c: df00 svc 0

The address of the function testFunc() is stored in register 12 (ip) as wanted.

However, when I try to put the same code in a templated function, the assembly is not correct anymore:

template<void(*F)()>
__attribute__((always_inline))
static inline void storeR12template()
{
   register uint32_t r asm("r12");
   r = (uint32_t)F;
   asm volatile ("svc 0" : : "r"(r) : "r0","r1");
}

results in:
   register uint32_t r asm("r12");
   r = (uint32_t)F;
 800036e: 4c03 ldr r4, [pc, #12] ; (800037c <main+0x18>)
   asm volatile ("svc 0" : : "r"(r) : "r0","r1");
 8000370: df00 svc 0

The value is only loaded into r4 and not moved to r12 anymore.

I am using GCC 6.2 2016q4 (binary release, windows) with the c++11 option and:
-O0 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mcpu=cortex-m4 -ffunction-sections -mthumb

compiled on a 64bit intel core i5-3230

Thank you,
Best regards
Daniel - <email address hidden>

description: updated
description: updated
description: updated
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.