On Mon, 2011-12-05 at 08:07 +0900, Kaz Kojima wrote:
> + return \"\\
> +mova\\t1f, r0\\n\\
> +\\t<i124extend_insn>\\t%2, %4\\n\\
> +\\tmov\\tr15, r1\\n\\
> +\\tmov\\t#(0f-1f), r15\\n\\
> +0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
> +\\tcmp/eq\\t%0, %4\\n\\
> +\\tbf\\t1f\\n\\
> +\\tmov.<i124suffix>\\t%3, @%1\\n\\
> +\\t.align\\t2\\n\\
> +1:\\tmov\tr1, r15\";
> +}"
> + [(set_attr "length" "20")])
> +
The function (C++11)...
#include <atomic>
int test (std::atomic<int>& val, int x)
{
return val += x;
}
results in...
mova 1f, r0 ! 7 atomic_add_fetchsi_soft [length = 16]
mov r15, r1
mov #(0f-1f), r15
0: mov.l @r4, r2
add r5, r2
mov.l r2, @r4
.align 2
1: mov r1, r15
rts ! 27 *return_i [length = 2]
mov r2,r0 ! 12 movsi_ie/2 [length = 2]
If I remember correctly, the ISR code in a gUSA implementation does
something like this:
if (interrupted_r15 < 0
&& interrupted_pc < atomic_exitpoint)
interrupted_pc = interrupted_r0 + interrupted_r15;
This works only if the exit point is right after the write-back insn.
However the above code might end up as:
mova 1f, r0
mov r15, r1
mov #(0f-1f), r15
0: mov.l @r4, r2
add r5, r2
mov.l r2, @r4 <-- write-back
nop <-- nop inserted to satisfy .align 2
1: mov r1, r15 <-- exit point
rts
mov r2,r0
... which means that if the atomic seauence is interrupted at the nop
insn, it would get rewound because it hasn't reached the exit-point yet.
This would make the atomic sequence execute twice, which is not correct.
The .align 2 should be placed somewhere before the write-back insn, or
am I missing something here?
Cheers,
Oleg