这个带输入=输出的gcc样式asm是否需要早期的破坏?

Pee*_*oot 7 gcc inline-assembly

Gcc内联asm早期clobber约束在这里的gcc文档中描述:

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

我们有128位add的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, ...) */ \
           )
Run Code Online (Sandbox Code Playgroud)

我想知道这是否必须使用%0的早期clobber(&):

#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, ...) */ \
           )
Run Code Online (Sandbox Code Playgroud)

但是,我不太确定,因为我们在amd64版本中明确地输入=输出(%0== %4,%1== %5)?

第一个非早期版本似乎目前适用于我们正在使用的所有优化级别,至少使用intel编译器(如果使用gcc,我们不需要这个,因为gcc现在支持对此目标的本机int128操作).

为了严格遵守inline asm中早期clobber的gcc规范,我们是否需要&for the %0约束,即使使用inputs = outputs语句?

Chr*_*odd 1

bh如果您使用与和完全相同的表达式调用此宏,则需要早期破坏al。在这种情况下,如果没有破坏,编译器可能会选择对%3and使用相同的寄存器%4(与 相同%0),因此第一条指令可能会在第二个表达式读取该值之前破坏该值。

您实际上不太可能以可能触发此问题的方式调用宏,因此如果没有破坏,您看不到任何问题也就不足为奇了。al当您调用具有相同的宏时,添加破坏还会引入额外的(不需要的)寄存器副本bl(例如,在适当的位置向其自身添加 128 位值),因此有点不可取。