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

Reply via email to