
Rene Rivera wrote:
Peter Dimov wrote:
Rene Rivera wrote:
OK, I tried translating the gcc_x86. But I just don't understand the GCC machine description language well enough. What does the assembly end up being for all those memory, cc, etc. ?
I don't think that CodeWarrior has any way of specifying whether an asm statement affects memory, clobbers a register, or should not be reordered. It's supposedly (and hopefully) smart enough to figure these things out on its own. ;-)
It is smart enough, and you have to jump some hoops to make it optimize assembly blocks.. But I also meant all the other GCC constructs that I don't know :-) For example MOVL is not x86 assembly, but some GCC construct, and I'm not totally sure yet if it's just the argument inverted version of MOV.
Yes, movl is the argument-inverted mov.
This is what I came up with for the atomic_conditional_increment..
inline int atomic_conditional_increment( int * pw ) { // int rv = *pw; // if( rv != 0 ) ++*pw; // return rv;
int rv; int register tmp;
asm { mov eax, [pw] L0: test eax, eax je L1 mov tmp, eax inc tmp lock cmpxchg [pw], tmp jne L0 L1: mov rv, eax //~ "movl %0, %%eax\n\t" //~ "0:\n\t" //~ "test %%eax, %%eax\n\t" //~ "je 1f\n\t" //~ "movl %%eax, %2\n\t" //~ "incl %2\n\t" //~ "lock\n\t" //~ "cmpxchgl %2, %0\n\t" //~ "jne 0b\n\t" //~ "1:": //~ "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) //~ "m"( *pw ): // input (%3) //~ "cc" // clobbers }
return rv; }
But, even though the logic seems correct to me, it doesn't work.
Assuming CodeWarrior returns in eax, try: inline int atomic_conditional_increment( int * pw ) { // int rv = *pw; // if( rv != 0 ) ++*pw; // return rv; asm { mov esi, [pw] mov eax, [esi] L0: test eax, eax je L1 mov ebx, eax inc ebx lock cmpxchg [esi], ebx jne L0 L1: } } // esi == pw, eax == *pw