Cortex-M7:在汇编程序中将 64 位无符号整数转换为单精度浮点数的最有效方法是什么?

Cortex-M7: What's the most efficient way to convert a 64-bit unsigned integer to a single-precision floating point number in assembler?

当我想将一个32位无符号整数(例如驻留在寄存器r0中)转换为VFP的单精度浮点数(例如存储在s0中)时,我使用:

vmov.f32        s0, r0
vcvt.f32.u32    s0, s0

然而,令人惊讶的是(至少对我而言)没有用于将 64 位无符号或有符号整数转换为单精度(或双精度)浮点数的汇编指令。

我完成这项工作的方式如下:

bottomInt       .req r0
topInt          .req r1
bottomFloat     .req s0
topFloat        .req s1

@ Convert the 64-bit unsigned int:
vmov.f32         bottomFloat, bottomInt             
vcvt.f32.u32     bottomFloat, bottomFloat
vmov.f32         topFloat, topInt
vcvt.f32.u32     topFloat, topFloat

@ Prepare multiplication with 2^32:
multiplierInt    .req r2                            
multiplierFloat  .req s2
mov              multiplierInt, #0x10000
vmov.f32         multiplierFloat, multiplierInt
vcvt.f32.u32     multiplierFloat, multiplierFloat

@ Multiply the upper word of the unsigned int:
vmul.f32         topFloat, multiplierFloat          
vmul.f32         topFloat, multiplierFloat

@ Add the two floating-point numbers:
vadd.f32         finalFloat, topFloat, bottomFloat

是否有更好、更优雅的方法来完成此操作?

即使可以表示准确的结果,您提出的方法也不准确,所以我不会使用它。

运行时库函数 __aeabi_ul2f__aeabi_ul2d 提供您所请求的确切行为。

在一般情况下,我建议您只调用这些函数。 例如,像:https://godbolt.org/z/j7jT6eWGY

如果(且仅当)您需要在程序中的 hot-spot 代码段中重复执行此操作,以至于您无法承担函数调用的开销,那么我建议您反汇编这些函数的库代码并将其内联。