Force Clang to “perform math early” on constant values

只愿长相守 提交于 2019-12-05 07:17:03
Brett Hale

Since you seem to be out of luck trying to force a constant evaluation due to design decisions, the ror r/m8, cl form might be a good compromise:

__asm__ ("rorb %b1, %b0" : "+q,m" (x) : "c,c" (y) : "cc");

The multiple alternative constraint syntax is to 'promote' register use over memory use due to an issue with clang, covered here. I don't know if this issue has been resolved in later versions. gcc tends to be better at constraint matching and avoiding spills.

This does require loading (y) into the rcx/ecx/cl register, but the compiler can probably hide it behind another latency. Furthermore, there are no range issues for (y). rorb effectively uses (%cl % 8). The "cc" clobber isn't required.


If an expression is constant, both gcc and clang can use __builtin_constant_p :

if (__builtin_constant_p(y))
    __asm__("rorb %1, %b0" : "+q,m" (x) : "N,N" ((unsigned char) y) : "cc");
else
    ... non-constant (y) ...

or as alluded to in the mailing list:

if (__builtin_constant_p(y))
{
    if ((y &= 0x7) != 0)
        x = (x >> y) | (x << (8 - y)); /* gcc generates rotate. */
}

If 'N' contraint for 8 bit , then how about 16/32/64?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!