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