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.
24 lines
713 B
C
24 lines
713 B
C
void __attribute__((naked)) cas(int *a, int *b) {
|
|
// This atomic sequence implements a copy-and-swap function. This test should
|
|
// stop at the first instruction, and after step instruction, we should stop
|
|
// at the end of the sequence (on the ret instruction).
|
|
asm volatile("1:\n\t"
|
|
"lr.w a2, (a0)\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"
|
|
"beqz a5, 1b\n\t"
|
|
"nop\n\t"
|
|
"2:\n\t"
|
|
"ret\n\t");
|
|
}
|
|
|
|
int main() {
|
|
int a = 4;
|
|
int b = 2;
|
|
cas(&a, &b);
|
|
}
|