错误:匹配约束在输出操作数中无效

时间:2018-11-26 11:04:11

标签: gcc inline-assembly powerpc altivec

我无法让GCC内联汇编程序接受Power9的某些内联汇编。

我要让GCC接受的常规程序集是darn 3, 1,其中3r3,而1是在文档中称为L的参数。它在big-endian上反汇编:

0:   e6 05 61 7c    darn    r3,1

在小端上:

0:   7c 61 05 e6    darn    r3,1

由于各种原因和问题,包括旧的编译器和冒充其他编译器的编译器,我想为指令发布字节码。我的测试程序:

gcc112:~$ cat test.c
#include <stdint.h>

void random()
{
  volatile uint64_t x = __builtin_darn();

  __asm__ __volatile__ ("darn 3, 1");

  uint64_t y;
  __asm__ __volatile__ (".byte 0x7c, 0x61, 0x05, 0xe6  \n" : "=r3" (y));
}

编译它会导致:

$ /opt/cfarm/gcc-latest/bin/gcc -mcpu=power9 -c test.c
test.c: In function 'random':
test.c:10:3: error: matching constraint not valid in output operand
   __asm__ __volatile__ (".byte 0x7c, 0x61, 0x05, 0xe6  \n" : "=r3" (y));
   ^~~~~~~
test.c:10:3: error: matching constraint not valid in output operand
test.c:10:3: error: invalid lvalue in asm output 0

这是GCC内联汇编手册中应涵盖的部分,但我看不出它是什么6.45.2.3 Output Operands。我还检查了简单和机器约束,但没有看到。

如何告诉GCC执行指令,然后将r3移至y


我们在x86上使用rdrand做同样的事情。在2.9版以上的所有GCC版本上,它都可以正常工作:

uint64_t temp;
__asm__ __volatile__
(
    // radrand rax with retry
    "1:\n"
    ".byte 0x48, 0x0f, 0xc7, 0xf0;\n"
    "jnc 1b;\n"
    : "=a" (temp)
    : : "cc"
);

1 个答案:

答案 0 :(得分:1)

将我的(未经测试的)评论移至答案以尝试解决此问题

我不熟悉r3作为输出约束。我猜想这是为了指示输出将在“ r3”寄存器中,但是我认为您不能以这种方式进行操作(尽管我不是powerpc的machine constraints专家)。相反,也许您可​​以尝试:

register uint64_t y asm("r3");

(例如将y设为local register variable),然后仅使用“ = r”作为约束?