Hello!
I recently discovered a problem that affects my entire code base. I
often do things like this:

    volatile unsigned char state;
    ...
    state |= (state >> 1) & DIRTY_FLAG;

Since ISR's might be trying to set DIRTY_FLAG at the same time, it is
very important that the final "|=" instruction happens atomically,
like with a "BIS.B foo, &state" instruction. This was my original
expectation, but the compiler apparently generates code like this
instead:

    MOV.B  &state, R15
    MOV.B  &state, R14
    RRUM   #0x0001, R15
    AND.B  #0x0002, R15
    BIS.B  R14, R15
    MOV.B  R15, &state

As you can see, there is a window of about three instructions where
changes from an ISR would be lost. I could surround this code with
__eint() / __dint() calls, but that seems overkill. I really want the
compiler to generate code like this:

    MOV.B  &state, R15
    RRUM   #0x0001, R15
    AND.B  #0x0002, R15
    BIS.B  R15, &state

Besides being smaller and faster, this actually does the right thing.

So, what do I do? Short-term options include rewriting the critical
bits in assembly and/or inserting the __eint() / __dint() calls, but I
am really looking for a more elegant long-term solution. Fixing the
code generator would be one option, but adding set of intrinsics like
__atomic_add() would also be nice, since those would document the
intention as well.

-William

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to