如果我有以下C++代碼比較兩個128位無符號整數,直列AMD-64 ASM:在GCC風格的擴展內聯asm中,是否可以輸出「虛擬化」布爾值,例如進位標誌?
struct uint128_t {
uint64_t lo, hi;
};
inline bool operator< (const uint128_t &a, const uint128_t &b)
{
uint64_t temp;
bool result;
__asm__(
"cmpq %3, %2;"
"sbbq %4, %1;"
"setc %0;"
: // outputs:
/*0*/"=r,1,2"(result),
/*1*/"=r,r,r"(temp)
: // inputs:
/*2*/"r,r,r"(a.lo),
/*3*/"emr,emr,emr"(b.lo),
/*4*/"emr,emr,emr"(b.hi),
"1"(a.hi));
return result;
}
然後,它會被非常有效地內聯,但是有一個缺陷。返回值是通過通用寄存器的「接口」完成的,值爲0或1.這將增加兩到三個不必要的額外指令,並減少比較操作的數量,否則會進行完全優化。生成的代碼將是這個樣子:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
setc al
movzx eax, al
test eax, eax
jnz is_lessthan
如果我使用「SBB%0%0」與「INT」返回值,而不是「國家經貿委%0」與「布爾」返回值,有仍然是兩個額外的指令:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
sbb eax, eax
test eax, eax
jnz is_lessthan
我想是這樣的:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
jc is_lessthan
GCC擴展內聯彙編是美妙的,否則。但我希望它能像內在功能一樣好,無論如何。我希望能夠以CPU標誌或標誌狀態的形式直接返回布爾值,而不必將其「渲染」爲通用寄存器。
這是可能的,還是GCC(和英特爾C++編譯器,它也允許使用這種形式的內聯asm)必須被修改或甚至重構使之成爲可能?
另外,雖然我在這 - 有沒有其他方法可以改進我的比較運算符的表達式?
截至2013年,似乎仍無法直接進行。但是這裏有一個2011年的bug報告,討論這種功能的可取性:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611。它鏈接到一個2001 Linux內核線程也希望這樣的事情:http://lkml.indiana。埃杜/ hypermail/LINUX /內核/ 0111.2/0256.html。 – 2013-10-24 09:25:28