I'm trying to write atomic code, in my example below I need to perform simple operation a ^= 1;
static volatile int a = 0;
//-- a ^= 1;
__asm__ __volatile__( "xori %0, %0, 1"
: "=r"(a)
: "r"(a)
);
Generated code is not atomic:
9D0014E8 8F828018 LW V0, -32744(GP)
9D0014EC 38420001 XORI V0, V0, 1
9D0014F0 AF828018 SW V0, -32744(GP)
As I see in docs, operations LL and SC provide atomic Read-Modify-Write sequence. How can I make compiler to generate code with LL, SC instead of LW, SW? I tried to write such code myself:
static volatile int a = 0;
__asm__ __volatile__( "ll $t1, 0(%0)": : "r"(a) );
__asm__ __volatile__( "xori $t1, $t1, 1" );
__asm__ __volatile__( "sc $t1, 0(%0)": : "r"(a) );
But this is wrong, result is other than I need:
140: __asm__ __volatile__( "ll $t1, 0(%0)": : "r"(a) );
9D001454 8F828018 LW V0, -32744(GP) # WRONG! | I need for LL T1, -32744(GP) instead of
9D001458 C0490000 LL T1, 0(V0) # WRONG! | these two LW, LL instructions
141: __asm__ __volatile__( "xori $t1, $t1, 1" );
9D00145C 39290001 XORI T1, T1, 1
142: __asm__ __volatile__( "sc $t1, 0(%0)": : "r"(a) );
9D001460 8F828018 LW V0, -32744(GP) # WRONG! | I need for SC T1, -32744(GP) instead of
9D001464 E0490000 SC T1, 0(V0) # WRONG! | these two LW, SC instructions
How can I do that?