Estoy intentando escribir código atómico, en mi ejemplo a continuación, necesito realizar la operación simple a ^= 1;
static volatile int a = 0;
//-- a ^= 1;
__asm__ __volatile__( "xori %0, %0, 1"
: "=r"(a)
: "r"(a)
);
El código generado no es atómico:
9D0014E8 8F828018 LW V0, -32744(GP)
9D0014EC 38420001 XORI V0, V0, 1
9D0014F0 AF828018 SW V0, -32744(GP)
Como veo en los documentos, las operaciones LL y SC proporcionan una secuencia atómica de lectura-modificación-escritura. ¿Cómo puedo hacer un compilador para generar código con LL, SC en lugar de LW, SW? Intenté escribir ese código yo mismo:
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) );
Pero esto es incorrecto, el resultado es distinto de lo que necesito:
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
¿Cómo puedo hacer eso?