ARM Cortex-M Broken Binaries with -O2 and -O3 (-fschedule-insns)

Mike via D.gnu d.gnu at puremagic.com
Sat Jul 22 01:11:28 PDT 2017


On Friday, 21 July 2017 at 23:44:53 UTC, Mike wrote:

> However, I'm getting broken binaries with -O2 and -O3.  I've 
> nailed the culprit down to -fschedule-insns (i.e. if I add 
> -fno-schedule-insns to -O2 or -O3, the binary works fine).

I've confirmed that -fschedule-insns is reordering register 
access even though they are being accessed with 
volatileLoad/Store.  Read the comments in the following code for 
understanding.  FYI A bit-banded address is a 32-bit address to a 
single bit.

Here's the D code
-----------------
// This is a single atomic store to bit-banded address 0x42470048
RCC.CR.HSEBYP.value = false;

// This is a single read-modify-write to non-bit-banded 32-bit 
address 0x40023808
with(RCC.CFGR)
{
     setValue
     !(
           MCO2,    0
         , MCO2PRE, 0
         , MCO1PRE, 0
         , I2SSRC,  0
         , MCO1,    0
         , RTCPRE,  0
         , HPRE,    0b000
         , PPRE2,   0b100
         , PPRE1,   0b101
         , SW,      0
     )();
}

And here's the dis-assembly
--------------------------_
8000b92:    ldr      r2, [pc, #188]  ; (8000c50 
<hardwareInit+0x104>)  0x40023808 - RCC.CFGR
8000b94:    ldr      r1, [pc, #188]  ; (8000c54 
<hardwareInit+0x108>)  0x40023808 - RCC.CR.HSEBYP

; Read-modify of RCC.CFGR
8000b96:    ldr      r3, [r2, #0]
8000b98:    and.w    r3, r3, #780    ; 0x30c
8000b9c:    orr.w    r3, r3, #37888  ; 0x9400

8000ba0:    movs     r0, #0          ; #0 is `false` value for 
RCC.CR.HSEBYP
8000ba2:    str      r3, [r2, #0]    ; This is the store to 
RCC.CFGR
8000ba4:    strb     r0, [r1, #0]    ; This is the store to 
RCC.CR.HSEBYP
...
8000c50:    .word    0x40023808
8000c54:    .word    0x42470048


You can see that at 8000ba2 and 8000ba4 RCC.CFGR is written 
first.  But in the D code RCC.CR.HSEBYP should be written first.

Mike



More information about the D.gnu mailing list