Currently, the tests that check stepping through atomic sequences use a hardcoded step distance, which is unreliable because this distance depends on LLVM's codegeneration. The relocations that clang emits can change the distance of the step. Additionally, it was a poor idea to compute and check the step distance because that is not what we should actually be verifying. In the tests we already know where execution should stop after the step - for example, at a branch instruction - therefore, it is better to check the opcode of the instruction rather than the step distance. The step distance itself is not important and can sometimes be misleading. This patch rewrites the tests, so now they checks the opcode of the instruction after the step instead of the step distance.
23 lines
681 B
C
23 lines
681 B
C
void __attribute__((naked)) incomplete_cas(int *a, int *b) {
|
|
// Stop at the first instruction (an sc without a corresponding lr), then make
|
|
// a step instruction and ensure that execution stops at the next instruction
|
|
// (and a5, a2, a4).
|
|
asm volatile("1:\n\t"
|
|
"sc.w a5, a1, (a3)\n\t"
|
|
"and a5, a2, a4\n\t"
|
|
"beq a5, a1, 2f\n\t"
|
|
"xor a5, a2, a0\n\t"
|
|
"and a5, a5, a4\n\t"
|
|
"xor a5, a2, a5\n\t"
|
|
"sc.w a5, a1, (a3)\n\t"
|
|
"bnez a5, 1b\n\t"
|
|
"2:\n\t"
|
|
"ret\n\t");
|
|
}
|
|
|
|
int main() {
|
|
int a = 4;
|
|
int b = 2;
|
|
incomplete_cas(&a, &b);
|
|
}
|