【发布时间】:2019-04-28 00:26:54
【问题描述】:
我无法让 GCC 内联汇编器接受 Power9 的一些内联汇编。
我试图让 GCC 接受的常规程序集是darn 3, 1,其中3 是r3,1 是文档中称为L 的参数。它在 big-endian 上反汇编成这个:
0: e6 05 61 7c darn r3,1
在 little-endian 上:
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 做同样的事情。它在所有版本的 GCC 上都可以正常工作,回到 2.9:
uint64_t temp;
__asm__ __volatile__
(
// radrand rax with retry
"1:\n"
".byte 0x48, 0x0f, 0xc7, 0xf0;\n"
"jnc 1b;\n"
: "=a" (temp)
: : "cc"
);
【问题讨论】:
-
我不熟悉
r3作为输出约束。我猜这是为了表明输出将在 'r3' 寄存器中,但我认为你不能这样做(尽管我不是 powerpc 的machine 约束方面的专家)。也许您可以尝试register uint64_t y asm("r3");(即local register variable),然后只使用=r作为约束? -
How to have GCC combine "move r10, r3; store r10" into a "store r3"? 的可能重复项,我在其中发布了与 @David 基本相同的 register-asm 局部变量答案。
标签: gcc inline-assembly powerpc altivec