我很难让GCC内联汇编程序接受Power9的内联汇编。
我试图让GCC接受的常规程序集是
darn 3, 1
,其中
3
是
r3
和
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
. 它在所有版本的GCC上都能正常工作,回到2.9:
uint64_t temp;
__asm__ __volatile__
(
"1:\n"
".byte 0x48, 0x0f, 0xc7, 0xf0;\n"
"jnc 1b;\n"
: "=a" (temp)
: : "cc"
);