我有一些代码基本上需要在汇编语句中使用一个小的表达式,该表达式像i * 4一样微不足道,但是GCC似乎在编译时没有意识到这一点(尝试不使用-O标志和-O3 )。在以下用于第三种用法的代码段中,“i”和“n”约束都不起作用。

#include <stdint.h>
#include <stdlib.h>

#define SHIFT(h, l, c) __asm__ volatile ( \
    "shld %2, %1, %0\n\t" \
    "sal %2, %1\n\t" \
    : "+r"(h), "+r"(l) : "i"(c))

void main(void) {
  uint64_t a, b;
  SHIFT(a, b, 1); /* 1 */
  SHIFT(a, b, 2*4); /* 2 */
  size_t i;
  for(i=0; i<24; i++) {
    SHIFT(a, b, (i*4)); /* 3 */
  }
}

给出此错误:
temp.c:15: warning: asm operand 2 probably doesn’t match constraints
temp.c:15: error: impossible constraint in ‘asm’

我也试过
"shld $" #c ", %1...

但这有其自身的问题,因为在字符串化时保留了括号。我的意图是使整个循环展开,但是-funroll-all-loop似乎没有足够早地在过程中引起i * 4变为常数。有任何想法吗?替代方案很丑陋,但是如果有一种方法可以在宏中自动执行此操作,那总比没有好:
SHIFT(a, b, 1);
SHIFT(a, b, 2);
...
SHIFT(a, b, 24);

最佳答案

是否有任何特定原因将 asm 块标记为 Volatile ?在存在volatile的情况下,几乎不可能进行任何优化。

关于gcc - 有没有办法在gcc中使用内联asm使用在编译时求值的表达式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3775870/

10-11 15:39
查看更多