首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ARMv8浮点输出内联组件

ARMv8浮点输出内联组件
EN

Stack Overflow用户
提问于 2018-12-28 14:41:43
回答 3查看 1.9K关注 0票数 2

对于添加两个整数,我写:

代码语言:javascript
复制
int sum;
asm volatile("add %0, x3, x4" : "=r"(sum) : :);

我怎么才能用两只花车做这个呢?我试过:

代码语言:javascript
复制
float sum;
asm volatile("fadd %0, s3, s4" : "=r"(sum) : :);

但它给了我一个错误:

错误:操作数1应该是SIMD矢量寄存器--‘`fadd x0,s3,s4’

有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-27 10:14:09

%P ARMv7 double: 修饰符

GCC告诉我,ARMv7双打在bug.cgi?id=89482#c4上的修正是正确的,也许总有一天我应该停止懒惰和grep GCC:

main.c

代码语言:javascript
复制
#include <assert.h>

int main(void) {
    double my_double = 1.5;
    __asm__ (
        "vmov.f64 d0, 1.0;"
        "vadd.f64 %P[my_double], %P[my_double], d0;"
        : [my_double] "+w" (my_double)
        :
        : "d0"
    );
    assert(my_double == 2.5);
}

编译和运行:

代码语言:javascript
复制
sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-gcc -O3 -std=c99 -ggdb3 -march=armv7-a -marm \
  -pedantic -Wall -Wextra -o main.out main.c
qemu-arm -L /usr/arm-linux-gnueabihf main.out

反汇编包括:

代码语言:javascript
复制
   0x00010320 <+4>:     08 7b b7 ee     vmov.f64        d7, #120        ; 0x3fc00000  1.5
   0x00010324 <+8>:     00 0b b7 ee     vmov.f64        d0, #112        ; 0x3f800000  1.0
   0x00010328 <+12>:    00 7b 37 ee     vadd.f64        d7, d7, d0

在Ubuntu 16.04,GCC 5.4.0,QEMU 2.5.0测试。

源代码定义点

票数 1
EN

Stack Overflow用户

发布于 2019-01-03 23:30:29

由于寄存器在AArch64中可以有多个名称(v0、b0、h0、s0、d0都引用同一个寄存器),因此有必要在打印字符串中添加一个输出修饰符:

论哥德波特

代码语言:javascript
复制
float foo()
{
    float sum;
    asm volatile("fadd %s0, s3, s4" : "=w"(sum) : :);
    return sum;
}

double dsum()
{
    double sum;
    asm volatile("fadd %d0, d3, d4" : "=w"(sum) : :);
    return sum;
}

将产生:

代码语言:javascript
复制
foo:
        fadd s0, s3, s4 // sum
        ret     
dsum:
        fadd d0, d3, d4 // sum
        ret  
票数 2
EN

Stack Overflow用户

发布于 2018-12-30 05:56:18

"=r"是GP整数寄存器的约束。

GCC手册声称"=w"是AArch64上FP / SIMD寄存器的约束。但是如果你试着这样做的话,你可以得到v0 s0**,而不是s0**,,它不会组装。**我不知道这里有什么解决办法,你可能应该报告一下gcc bugzilla,手册中记录的约束对于标量FP不起作用。

论哥德波特我尝试了这个来源:

代码语言:javascript
复制
float foo()
{
    float sum;
#ifdef __aarch64__
    asm volatile("fadd %0, s3, s4" : "=w"(sum) : :);   // AArch64
#else
    asm volatile("fadds %0, s3, s4" : "=t"(sum) : :);  // ARM32
#endif
    return sum;
}

double dsum()
{
    double sum;
#ifdef __aarch64__
    asm volatile("fadd %0, d3, d4" : "=w"(sum) : :);   // AArch64
#else
    asm volatile("faddd %0, d3, d4" : "=w"(sum) : :);  // ARM32
#endif
    return sum;
}

clang7.0 (及其内置汇编程序)要求asm实际上是有效的。但是对于gcc来说,我们只是在编译asm,而且对于非x86,戈德波特没有“二进制模式”。

代码语言:javascript
复制
# AArch64 gcc 8.2  -xc -O3 -fverbose-asm -Wall
# INVALID ASM, errors if you try to actually assemble it.
foo:
    fadd v0, s3, s4 // sum
    ret     
dsum:
    fadd v0, d3, d4 // sum
    ret

clang生成相同的asm,其内置汇编程序错误有:

代码语言:javascript
复制
<source>:5:18: error: invalid operand for instruction
    asm volatile("fadd %0, s3, s4" : "=w"(sum) : :);
                 ^
<inline asm>:1:11: note: instantiated into assembly here
        fadd v0, s3, s4
             ^

On 32位ARM=t"用于单件作品,但"=w" (手册中说您应该使用双精度)也给了您s0和gcc。不过,它适用于clang。你必须使用-mfloat-abi=hard-mcpu=,比如-mcpu=cortex-a15

代码语言:javascript
复制
# clang7.0 -xc -O3 -Wall--target=arm -mcpu=cortex-a15 -mfloat-abi=hard
# valid asm for ARM 32
foo:
        vadd.f32        s0, s3, s4
        bx      lr
dsum:
        vadd.f64        d0, d3, d4
        bx      lr

但gcc失败了:

代码语言:javascript
复制
# ARM gcc 8.2  -xc -O3 -fverbose-asm -Wall -mfloat-abi=hard -mcpu=cortex-a15
foo:
        fadds s0, s3, s4        @ sum
        bx      lr  @
dsum:
        faddd s0, d3, d4        @ sum    @@@ INVALID
        bx      lr  @

因此,您可以在gcc的情况下单独使用=t,但是对于double,您可能需要一个%something0修饰符将注册名打印为d0而不是s0,并带有"=w"输出。

显然,如果添加约束来指定输入操作数,而不是读取s3和s4中发生的任何情况,这些asm语句只对学习语法之外的任何内容都有帮助。

另见https://stackoverflow.com/tags/inline-assembly/info

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53960240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档