2010-12-16 48 views
1

我从来没有做过装配(从前),并从未做过任何x86,但我发现了旧的现有代码中有人没有做一个原子操作,他们应该在哪里讨厌的bug。编写代码的人早已离去,周围没有人知道我的问题的答案。我需要做的是为128位值创建一个原子副本。我目前拥有的代码如下:如何在gcc内联x86_64 asm中执行128位数字的原子副本?

void atomic_copy128(volatile void* dest,volatile const void* source) { 
#if PLATFORM_BITS == 64 
    #ifdef __INTEL_COMPILER 
     //For IA64 platform using intel compiler 
     *((__int64*)source)=__load128((__int64*)dest,((__int64*)source)+1); 
    #else 
     //For x86_64 compiled with gcc 
     __asm__ __volatile__("lock ; movq %0,%1" 
      : "=r"(*((volatile long *)(source))) 
      : "r"(*((volatile long *)(dest))) 
      : "memory"); 
    #endif 
#else 
    #error "128 bit operations not supported on this platform." 
#endif 
} 

这不是我原来试过,因为我已经用它搞砸了不少,而试图得到它的编译和运行代码。当我使它成为一个完全无效的指令时,它不会编译。当我运行它时,它会执行直到它遇到这一行,然后生成一条“非法指令”错误消息。我会很感激任何帮助。

回答

1

据我所知,“movq”最多支持一个内存操作数,它的参数无论如何都是64位大小,所以即使支持两个内存操作数,它仍然不会给你原子128您正在寻找的位拷贝。

+0

感谢您的答复!我认为“movdqu”也只允许最多一个内存操作数?如果是这样,那么我真的有办法将它用于原子拷贝操作,因为我无法在一条指令中做到这一点,对吗?我在想这个全错吗? – user545226 2010-12-17 19:33:45

+0

FWIW,我相信你在这两方面都是正确的。 – 2010-12-17 23:14:46

0

对于Windows:

::memset(dst, -1, 16); 
_InterlockedCompareExchange128(source, -1, -1, dst); 

(但const必须删除)

用于其他用途cmpxchg16b指令