2012-06-19 70 views
7

gcc的內聯彙編早期撞約束這裏描述在這裏GCC文檔:這個輸入=輸出的gcc樣式asm是否需要早期的clobber?

http://gcc.gnu.org/onlinedocs/gcc/Modifiers.html#Modifiers

我們128位的AMD64實現補充:

#define ADD128(rh, rl, ah, al, bh, bl)          \ 
    __asm__("addq %2, %0; adcq %3, %1"          \ 
      /* outputs */ : "=r"(rl), /* %0 */       \ 
          "=r"(rh) /* %1 */       \ 
      /* inputs */ : "emr"(bl), /* %2 */       \ 
          "emr"(bh), /* %3 */       \ 
          "0"(al), /* %4 == %0 */      \ 
          "1"(ah) /* %5 == %1 */      \ 
      /* clobbers */: "cc"  /* condition registers (CF, ...) */ \ 
      ) 

我想知道,這必須使用早期撞(&)用於%0:

#define ADD128(rh, rl, ah, al, bh, bl)         \ 
    __asm__("addq %2, %0; adcq %3, %1"          \ 
      /* outputs */ : "=&r"(rl), /* %0 */       \ 
          "=r"(rh) /* %1 */       \ 
      /* inputs */ : "emr"(bl), /* %2 */       \ 
          "emr"(bh), /* %3 */       \ 
          "0"(al), /* %4 == %0 */      \ 
          "1"(ah) /* %5 == %1 */      \ 
      /* clobbers */: "cc"  /* condition registers (CF, ...) */ \ 
      ) 

但是,我不敢肯定小號因此,我們在amd64版本中明確指定輸入=輸出(%0 == %4%1 == %5)?

第一個非earlyclobber版本似乎目前在我們正在使用的所有優化級別上工作,至少在intel編譯器中(如果使用gcc,我們不需要這個,因爲gcc現在支持本目標上的本地int128操作) 。

爲了嚴格遵守內聯asm中早期clobber的gcc規範,我們需要&作爲%0約束,即使使用inputs = outputs語句?

回答

1

如果你使用與bhal完全相同的表達式調用此宏,則需要早期的clobber。在那種情況下,如果沒有clobber,編譯器可能會選擇對%3%4(與%0相同)使用相同的寄存器,因此第一條指令可能會在第二條表達式讀取該值之前將該值重新打開。

它實際上不太可能會以可能引發此問題的方式調用宏,因此,如果沒有clobber,就不會看到任何問題。當你用與bl相同的al來調用宏時(例如,在自己的位置上增加一個128位的值),添加clobber還會引入額外的(不需要的)寄存器副本,所以稍微不合需要。