On Saturday, 22 July 2017 at 01:11:02 UTC, Mike wrote:
On Friday, 21 July 2017 at 23:44:53 UTC, Mike wrote:

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 disassembled '-O2' and '-O2 -fno-schedule-insns' and compared them, but they were quite different all the way through. No only because of address locations, but also different registers and even different opcodes. (e.g. 'str r2, [sp, #12]' vs 'strd r1, r2, [sp, #8]')

Interestingly, I added a stategically placed `asm { "nop"; }` and my binary was able to execute further. Comparing the disassembly of the function I modified still showed quite a significant difference.

Working Binary
-------------
ldr     r2, [pc, #188]  ; (8000c50 <hardwareInit+0x104>)
ldr     r1, [pc, #188]  ; (8000c54 <hardwareInit+0x108>)
ldr     r3, [r2, #0]
and.w   r3, r3, #780    ; 0x30c
orr.w   r3, r3, #37888  ; 0x9400
movs    r0, #0
str     r3, [r2, #0]
strb    r0, [r1, #0]
;-------------------------------------------------------
nop                     ; My stategically placed nop
;-------------------------------------------------------
ldr     r3, [pc, #172]  ; (8000c58 <hardwareInit+0x10c>)
ldr     r0, [pc, #176]  ; (8000c5c <hardwareInit+0x110>)
ldr     r4, [pc, #176]  ; (8000c60 <hardwareInit+0x114>)
ldr     r2, [pc, #180]  ; (8000c64 <hardwareInit+0x118>)
movs    r1, #1
strb    r1, [r3, #0]
ldr     r3, [r0, #0]
orr.w   r3, r3, #49152  ; 0xc000
str     r3, [r0, #0]
strb    r1, [r4, #0]

Not Working Binary
------------------
ldr     r0, [pc, #184]  ; (8000c4c <hardwareInit+0x100>)
ldr     r1, [pc, #184]  ; (8000c50 <hardwareInit+0x104>)
ldr     r2, [pc, #188]  ; (8000c54 <hardwareInit+0x108>)
ldr     r3, [r1, #0]
ldr     r4, [pc, #188]  ; (8000c58 <hardwareInit+0x10c>)
movs    r5, #0
strb    r5, [r0, #0]
movs    r0, #1
strb    r0, [r2, #0]
ldr     r2, [r4, #0]
ldr     r5, [pc, #180]  ; (8000c5c <hardwareInit+0x110>)
orr.w   r2, r2, #49152  ; 0xc000
and.w   r3, r3, #780    ; 0x30c
str     r2, [r4, #0]
orr.w   r3, r3, #37888  ; 0x9400
ldr     r2, [pc, #168]  ; (8000c60 <hardwareInit+0x114>)
strb    r0, [r5, #0]
str     r3, [r1, #0]

By "Not Working" I mean this code gets stuck in the while loop

PWR.CR.ODEN.value = true;
while(!PWR.CSR.ODRDY.value) { }

This is simply setting the "Overdrive Enable" register on the power control peripheral of my hardware. The documentation states:

To set or reset the ODEN bit, the HSI or HSE must be selected as system clock.

I'm setting the HSI prior to setting ODEN, but it appears that maybe the compiler is reordering the instructions. I still need to investigate that further, but hopefully that provides a little more insight.

Mike

A quick answer without looking your code: this never worked properly because the compiler thinks the value is not changing and may be optimized out of the loop. After this the test inside while may also be optimized outside. Then the whole while thing which now has nothing to test and nothing inside the body can be optimized out.

I got this working because 'shared' meant 'volatile' in gdc but this is not true any more. I did not yet look how you define your data type and how you access the data but it seems the compiler thinks it is an ordinary variable.

I made custom Volatile data type that uses those new compiler intrinsics and my sample program seems to work with gdc 7. The only thing that does not work is exceptions. The exception code in runtime has changed a lot so I do not know whether it should work or not.

Reply via email to