Pseudo op "ldr Rx, =#imm" doesn't work for hi regs

Asked by Elliot Buller on 2018-04-11

Not sure if I'm missing something so I haven't filed a bug report. This code appears to compile incorrectly.

int main (int argc, char **argv) {
  asm volatile ("ldr r6, =#8\n\t"
                         "ldr r8, =#8\n\t"
                         "ldr r9, =#8\n\t"
                          :::"r6","r8", "r9");
  return 0;

Compiled with: arm-none-eabi-gcc -march=armv7-m -mthumb -nostartfiles -nostdlib test.c

Generates this assembly:
0x60 <main+12> movs r6, #8
0x62 <main+14> cmp r0, #8
0x64 <main+16> cmp r1, #8

The movs also appears to be a bug as it updates the flags when it shouldn't. It seems this has already been reported and fixed in bug #1682620. For hi regs >7 it appears to fail to recognize this and generates a 16-bit instruction rather than the 32-bit variant. Register bitfield appears to overflow into bit 11 and generate a cmp instruction.

(gdb) x/3xh 0x60
0x60 <main+12>: 0x2608 0x2808 0x2908

Compiling with the following version: arm-none-eabi-gcc (15:4.9.3+svn231177-1) 4.9.3 20150529 (prerelease)

Maybe this has already been fixed? Let me know where to find a newer version to test, any help is appreciated.

Question information

English Edit question
GNU Arm Embedded Toolchain Edit question
No assignee Edit question
Solved by:
Elliot Buller
Last query:
Last reply:
Elliot Buller (tinylabs) said : #1

Upgraded to a newer version and this appears to be fixed.
    800c: f04f 0608 mov.w r6, #8
    8010: f04f 0808 mov.w r8, #8
    8014: f04f 0908 mov.w r9, #8

New version:
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204]