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 代码段中重复执行此操作,以至于您无法承担函数调用的开销,那么我建议您反汇编这些函数的库代码并将其内联。
当我想将一个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 代码段中重复执行此操作,以至于您无法承担函数调用的开销,那么我建议您反汇编这些函数的库代码并将其内联。