从uint64_t转换为double

时间:2019-02-05 16:26:49

标签: c arm armv7 stm32f7 libgcc

对于包含双浮点指令的STM32F7,我想将uint64_t转换为double

为了测试这一点,我使用了以下代码:

volatile static uint64_t m_testU64 = 45uLL * 0xFFFFFFFFuLL;
volatile static double m_testD;

#ifndef DO_NOT_USE_UL2D
    m_testD = (double)m_testU64;
#else
    double t = (double)(uint32_t)(m_testU64 >> 32u);
    t *= 4294967296.0;
    t += (double)(uint32_t)(m_testU64 & 0xFFFFFFFFu);
    m_testD = t;
#endif

默认情况下(如果未定义DO_NOT_USE_UL2D,编译器(gcc或clang)将调用函数:__aeabi_ul2d(),该函数执行的指令数量复杂。请在此处查看汇编代码:https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/arm/ieee754-df.S#L537

在我的特定示例中,无需输入大多数分支即可花费20条指令

如果定义了DO_NOT_USE_UL2D,则编译器将生成以下汇编代码:

movw    r0, #1728       ; 0x6c0
vldr    d2, [pc, #112]  ; 0x303fa0
movt    r0, #8192       ; 0x2000
vldr    s0, [r0, #4]
ldr     r1, [r0, #0]
vcvt.f64.u32    d0, s0
vldr    s2, [r0]
vcvt.f64.u32    d1, s2
ldr     r1, [r0, #4]
vfma.f64        d1, d0, d2
vstr    d1, [r0, #8]

代码更简单,只有10条指令。

这里是问题(如果定义了DO_NOT_USE_UL2D):

  • 我的代码(在C语言中)正确吗?
  • 我的代码是否比__aeabi_ul2d()函数慢(不是很重要,但有点奇怪)?

我必须这样做,因为不允许我使用libgcc中的函数(这样做的理由非常充分……)

请注意,此问题的主要目的不是性能,我对libgcc中的实现真的很好奇,我真的想知道我的代码中是否有错误。

0 个答案:

没有答案