gccthumb2内联汇编用于定点转换

问题描述 投票:0回答:1

我想为Cortex-M7上的armv7em编写一些gcc内联汇编来执行浮点数和定点数之间的转换。 ARM 提供带有 #fbits 的 vcvt 指令来实现这一点:ARM 指令文档。我很难找到正确的双精度实现。

对于浮动实现,我想出了以下代码:

float fractional_to_float(int32_t op1)
{
    float result;
    asm ("vmov.32 %0, %1\n\t"
         "vcvt.f32.s32 %0, %0, %2" :
         "=w"(result) :
         "r" (op1), "I" (FRACTIONAL_BITS) :
         /* no clobber */);
    return result;
}

int32_t float_to_fractional(float op1)
{
    int32_t result;
    asm ("vcvt.s32.f32 %1, %1, %2\n\t"
         "vmov.f32 %0, %1" :
         "=r"(result) :
         "w" (op1), "I" (FRACTIONAL_BITS) :
         /* no clobber */);
    return result;
}

双精度实现会是什么样子?我正在尝试想出这样的功能:

double fractional_to_double(int32_t op1);
int32_t double_to_fractional(double op1);
assembly gcc arm inline-assembly cortex-m
1个回答
0
投票

按照这个 godbolt 示例,您可以使用寄存器变量来强制使用双寄存器。

#include <stdlib.h>
#define FRACTIONAL_BITS 4
int test (double d) {
    register double target asm ("d0") = d;
    int result;
     asm ("vcvt.s32.f64 d0, %0, %2\r\n" :
         "=r"(result) : "w" (target), "I" (FRACTIONAL_BITS));
    return result;
}

这会产生汇编器,

test:
        vcvt.s32.f64 d0, r0, #4
        bx      lr

使用的编译器是 gcc 10.3.1 并使用了选项,

-mcpu=cortex-m7 -O3  -mfpu=fpv5-d16 -mfloat-abi=hard

将内联中显式的

d0
替换为
%1
会导致使用
s0
(与“target”或“d”一起使用)。 请注意,使用 EABI,浮点/双精度在“d0”中传递,因此这适用于函数,但如果您尝试内联(宏,只是 asm,内联函数),它可能会中断或至少导致无关的移动。

正如我在上面的评论中所述,有效的说明符将是最好的,但似乎记录的“w”仅选择浮点寄存器。

© www.soinside.com 2019 - 2024. All rights reserved.