Преобразование из uint64_t в двойное - PullRequest
0 голосов
/ 05 февраля 2019

Для 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, и я действительно хочу знать, если что-то не так в моем коде.

...