2010-12-16 46 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指令