Нашел ошибку, правильно так: __asm__ __volatile__( "ll $t1, 0(%0)": : "r"(&a) );
__asm__ __volatile__( "xori $t1, $t1, 1" );
__asm__ __volatile__( "sc $t1, 0(%0)": : "r"(&a) );
Теперь сгенерированный код выглядит так:
104: __asm__ __volatile__( "ll $t1, 0(%0)": : "r"(&a) ); 9D001434 27828018 ADDIU V0, GP, -32744 9D001438 C0490000 LL T1, 0(V0) 105: __asm__ __volatile__( "xori $t1, $t1, 1" ); 9D00143C 39290001 XORI T1, T1, 1 106: __asm__ __volatile__( "sc $t1, 0(%0)": : "r"(&a) ); 9D001440 E0490000 SC T1, 0(V0)(В реале еще нужно не забыть про инструкцию beqz, чтобы повторить всю последовательность если SC выполнился с ошибкой. Пример есть в MIPS32 Instruction Set Quick Reference ) Плюс, на форуме microchip.com подсказали, что можно просто использовать GCC'шные атомарные встроенные функции, в данном случае __sync_fetch_and_xor(). Правда, ценой двух лишних инструкций sync, которые не нужны в PIC32.