2012-06-19 71 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还会引入额外的(不需要的)寄存器副本,所以稍微不合需要。