C global anonymous struct / union

前端 未结 6 1076
一个人的身影
一个人的身影 2021-01-26 14:53

I have a uint64 variable which often only requires high or low 32 bit access. I am using a 32-bit ARM Cortex M0, and to help with speed and I am trying to overlap the uint64 var

6条回答
  •  旧巷少年郎
    2021-01-26 14:59

    To clarify what I've learned:

    It turns out C doesn't allow global members of anonymous structs/unions. Oh well. But using named structs/unions generates efficient code anyway, as the member offset is known at compile time and can be added without incurring extra instructions.

    Regarding using shifts & masks instead of a union, this may work well for reads, but for writes it results in extra instructions (9 vs 5) and pointless accesses to the low uint32. On the other hand, it is more endian portable than a union, but that isn't important in my application.

    union status {
       struct { uint32_t user, system; };
       uint64_t all;
    };
    volatile union status status;
    
    status.system |= 1u;                // write to high uint32 member directly
    2301        movs r3, #1
    4A02        ldr r2, 0x00002910
    6851        ldr r1, [r2, #4]
    430B        orrs r3, r1
    6053        str r3, [r2, #4]
    
    status.all |= ((uint64_t)1)<<32;    // write to full uint64
    2001        movs r0, #1
    4905        ldr r1, 0x00002910
    680C        ldr r4, [r1]
    684D        ldr r5, [r1, #4]
    4328        orrs r0, r5
    1C22        adds r2, r4, #0
    1C03        adds r3, r0, #0
    600A        str r2, [r1]            // this is not atomic, and pointless
    604B        str r3, [r1, #4]        // this is the important part
    

提交回复
热议问题