gcc-arm-none-eabi-4_7-2012q4-20121208 broken for CMSIS

Asked by grissiom on 2012-12-28

I've upgrade to gcc-arm-none-eabi-4_7-2012q4-20121208 but found it could not compile my projects:

arm-none-eabi-gcc -o build/Libraries/CMSIS/CM3/CoreSupport/core_cm3.o -c -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -std=c99 -Wall -O2 -gdwarf-2 -Os -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD -DRT_USING_MINILIBC -Iapplications -Irt-thread/applications -I. -Irt-thread -Iapplications -Irt-thread/applications -I. -Irt-thread -Idrivers/lcd -Irt-thread/drivers/lcd -Idrivers -Irt-thread/drivers -Idrivers/touch -Irt-thread/drivers/touch -Idrivers -Irt-thread/drivers -Idrivers -Irt-thread/drivers -ILibraries/STM32F10x_StdPeriph_Driver/inc -Irt-thread/Libraries/STM32F10x_StdPeriph_Driver/inc -ILibraries/CMSIS/CM3/CoreSupport -Irt-thread/Libraries/CMSIS/CM3/CoreSupport -ILibraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x -Irt-thread/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x -Irt-thread/include -Irt-thread/rt-thread/include -Irt-thread/libcpu/arm/cortex-m3 -Irt-thread/rt-thread/libcpu/arm/cortex-m3 -Irt-thread/libcpu/arm/common -Irt-thread/rt-thread/libcpu/arm/common -Irt-thread/components/drivers/include -Irt-thread/rt-thread/components/drivers/include -Irt-thread/components/drivers/include -Irt-thread/rt-thread/components/drivers/include -Irt-thread/components/external/tjpgd1a -Irt-thread/rt-thread/components/external/tjpgd1a -Irt-thread/components/finsh -Irt-thread/rt-thread/components/finsh -Irt-thread/components/libc/minilibc -Irt-thread/rt-thread/components/libc/minilibc -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/include -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/common -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/server -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/widgets Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
/tmp/cc7HfyyL.s: Assembler messages:
/tmp/cc7HfyyL.s:508: Error: registers may not be the same -- `strexb r0,r0,[r1]'
/tmp/cc7HfyyL.s:533: Error: registers may not be the same -- `strexh r0,r0,[r1]'

I've added

#include <stdint.h>
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
   uint32_t result=0;

   __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
   return(result);
}

to share/gcc-arm-none-eabi/samples/src/minimum/minimum.c and the sample failed to compile as well:

arm-none-eabi-gcc minimum.c ../../startup/startup_ARMCM0.S -mthumb -mcpu=cortex-m0 -D__STARTUP_CLEAR_BSS -D__START=main -Os -ffunction-sections -fdata-sections --specs=nano.specs -lc -lc -lnosys -L. -L../../ldscripts -T gcc.ld -Wl,--gc-sections -Wl,-Map=minimum.map -o minimum-CM0.axf
/tmp/ccxAzAZy.s: Assembler messages:
/tmp/ccxAzAZy.s:22: Error: selected processor does not support Thumb mode `strexb r0,r0,[r1]'
make: *** [minimum-CM0.axf] Error 1

I think the toolchain is currently broken.

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:
2013-01-01
Last query:
2013-01-01
Last reply:
2013-01-01
IgorKossak (imah) said : #1

CodeSourcery recommendations:

Question

When compiling applications that contain or use the Cortex Microcontroller Software Interface Standard e.g. CMSIS (http://www.onarm.com/cmsis/) you may receive the following errors:
/tmp/ccaxp69S.s: Assembler messages:
/tmp/ccaxp69S.s:463: Error: registers may not be the same -- `strexb r0,r0,[r1]'
/tmp/ccaxp69S.s:488: Error: registers may not be the same -- `strexh r0,r0,[r1]'

How do I fix these "registers may not be the same" errors? Where do they come from?

Answer

Some versions of the CMSIS contain invalid inline assembly of the following form:
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
 uint32_t result=0;
 asm volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
 return(result);
}

The first constraint =r on variable result is not correct, it should be =&r to indicate that the two registers used should not be the same e.g. early-clobber (this is required by the ARM Instruction Set Architecture).

To fix the error you must locate the invalid inline assembly and change the =r to =&r for the result register variable.

Often it is difficult to determine which source file was used to generate /tmp/ccaxp69S.s, to help with that problem add -save-temps to the compiler invocation to save the intermediate output to the current directory for your review.

 This entry was last updated on 8 February 2012.

Terry Guo (terry.guo) said : #2

Thank both of you for trying our tool chain and share experience.

I just checked the M0 arch doc and found that the strexb is supported starting from armv7-m. So it makes sense to generate error message " selected processor does not support Thumb mode..." for cortex-m0.

For cortex-m3, it should work and we need to update "=r" to "=&r". In latest CMSIS, it is already updated. Here is the result of grep:

terguo01@sha-win-053 /cygdrive/d/work/cmsis/CMSIS_V3P00
$ grep -r "strexb" *
CMSIS/Include/core_cmInstr.h: __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );

You can upgrade your CMSIS to fix this issue. The latest CMSIS can be found at http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php.

grissiom (chaos.proton) said : #3

Hmm, "=&r" could resolve the problem. But, why Rn and Rt in STREX could not be the same? ARMĀ® v7-M Architecture Reference Manual(Derrata 2010_Q3) said:

STREXB<c> <Rd>,<Rt>,[<Rn>]
d = UInt(Rd); t = UInt(Rt); n = UInt(Rn);
if d IN {13,15} || t IN {13,15} || n == 15 then UNPREDICTABLE;
if d == n || d == t then UNPREDICTABLE;

But d == t is not a wrong case in the manual.

Besides, GCC 4.6 could compile the code. Which one is wrong?

Best Terry Guo (terry.guo) said : #4

I think we need to clarify something here:

1). This is an Assembler error message and nothing related to compiler. The gas 2.21 in 4.6 12Q4 release hasn't such check, so no this message. In this 4.7 release, the gas is upgraded to 2.22 and has such operands check, so we got this error message. And I think 2.22 is right because of item 2). The exact patch is at http://sourceware.org/ml/binutils/2011-07/msg00191.html.

2). For case with "=r", the generated instruction is something like "strexb r0,r0,[r1]". Here the Rn is r1, Rt and Rd is r0. Just as the manual said, the Rd had better to be different from Rt. So the Assembler 2.22 is complaining of two r0 registers, the same Rd and Rt. There is no complain on Rn and Rt. I think it is ok to make Rn and Rt in same register. Here is what I did:

terguo01@terry-pc01:launchpad-questions$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -c -Os m0.c
terguo01@terry-pc01:launchpad-questions$ arm-none-eabi-objdump -d m0.o

m0.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <__STREXB>:
   0: e8c1 1f43 strexb r3, r1, [r1]
   4: 4618 mov r0, r3
   6: 4770 bx lr
terguo01@terry-pc01:launchpad-questions$ cat m0.c
unsigned int __STREXB(unsigned int value, unsigned int *addr)
{
unsigned int result = 0;

__asm volatile ("strexb %0, %1, [%1]" : "=&r" (result) : "r" (addr), "r" (value));

return result;
}
terguo01@terry-pc01:launchpad-questions$

grissiom (chaos.proton) said : #5

Thanks Terry Guo, that solved my question.

Michael Fischer (emb4fun) said : #6

Hello,

I have tested the original example here with my Cortex-M3 example too.
I have added the code:

#define __ASM __asm
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
   uint32_t result=0;

   __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
   return(result);
}

And had no problems. I use the latest version under windows from 2012-12-24:

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (releas
e) [ARM/embedded-4_7-branch revision 194305]
Copyright (C) 2012 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.

I have added the code to my example here:
http://www.emb4fun.de/download/arm/examples/STM32Test.zip

It is strange that I does not get the error.

Best regards,
Michael

Terry Guo (terry.guo) said : #7

Hi Michael,

Can you please share your command line options on Windows? The original example is compiled with -O2. And with -O2, the tool chain on windows can generate this error in my environment:

 $ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -c m3.c -O2
D:\Cygwin\cygwin\tmp\ccjhexe2.s: Assembler messages:
D:\Cygwin\cygwin\tmp\ccjhexe2.s:26: Error: registers may not be the same -- `strexb r0,r0,[r1]'

And with -O0, there is no such error for tool chain on Windows and Linux.

So far I haven't observed any different behaviors between Windows and Linux tool chain.

Best regards,
Terry

Michael Fischer (emb4fun) said : #8

Hello Terry,

ups, here the same. I have not test it before with optimization.
My example use -O0, with 1,2 or 3 I got the same error message.

Best regards,
Michael