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

Reply via email to