寻求Cortex-M7(ARMv7EM)GCC双精度定点浮点转换内联汇编实现
Cortex-M7(ARMv7EM)双精度浮点数与定点数转换的GCC内联汇编实现
针对ARMv7EM架构的Cortex-M7处理器,利用ARM提供的带#fbits参数的VCVT指令可实现浮点数与定点数的转换。已完成单精度版本的实现,现给出对应的双精度转换函数方案。
单精度参考实现
// 定点数转单精度浮点数 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; }
双精度实现方案
核心区别在于双精度浮点寄存器使用d约束(对应ARM 64位浮点寄存器),指令替换为双精度版本的VCVT指令:
#include <stdint.h> // 定点数转双精度浮点数 double fractional_to_double(int32_t op1) { double result; // 将32位定点数加载到双精度浮点寄存器,执行定点转双精度转换 asm ("vmov.32 %0, %1\n\t" "vcvt.f64.s32 %0, %0, %2" : "=d"(result) : // 输出约束:双精度浮点寄存器d "r" (op1), "I" (FRACTIONAL_BITS) : // 输入约束:通用寄存器r、立即数I(fbits范围0-31) /* 无被破坏的寄存器 */); return result; } // 双精度浮点数转定点数 int32_t double_to_fractional(double op1) { int32_t result; // 执行双精度转32位定点数转换,将结果从浮点寄存器移到通用寄存器 asm ("vcvt.s32.f64 %1, %1, %2\n\t" "vmov.32 %0, %1" : "=r"(result) : // 输出约束:通用寄存器r "d" (op1), "I" (FRACTIONAL_BITS) : // 输入约束:双精度浮点寄存器d、立即数I /* 无被破坏的寄存器 */); return result; }
关键说明
- 寄存器约束:双精度浮点变量使用
d约束,区别于单精度的w约束 - 指令选择:使用
vcvt.f64.s32(定点转双精度)和vcvt.s32.f64(双精度转定点)指令完成对应转换 - 数据移动:通过
vmov.32指令在32位通用寄存器与64位浮点寄存器间传递定点数数据,适配int32_t的32位宽度
内容的提问来源于stack exchange,提问作者user27039317
相关产品推荐
相关产品推荐

