Я пытаюсь использовать следующий код для эмуляции 16-разрядного полуплавающего в программном обеспечении:
typedef struct half
{
unsigned short mantissa:10;
unsigned short exponent:5;
unsigned short sign:1;
} half;
unsigned short from_half(half h)
{
return h.mantissa | h.exponent << 10 | h.sign << 15;
}
half to_half(unsigned short s)
{
half result = { s, s >> 10, s >> 15 };
return result;
}
Я настроил это так, чтобы его можно было легко оптимизировать в инструкцию перемещения, но и вот, в from_half
G CC все равно выполняет сдвиг битов (даже при -O3
):
from_half:
mov edx, edi
mov eax, edi
and di, 1023
shr dx, 15
and eax, 31744
movzx edx, dl
sal edx, 15
or eax, edx
or eax, edi
ret
, в то время как to_half
прекрасно оптимизируется:
to_half:
mov eax, edi
ret
Godbolt
Я пробовал разные уровни оптимизации (-O1
, -O2
, -Os
), но никто не оптимизировал его до того, на что я надеялся.
Clang делает это так, как я ожидал, даже на -O1
:
from_half: # @from_half
mov eax, edi
ret
to_half: # @to_half
mov eax, edi
ret
Godbolt
Как я могу получить G CC, чтобы оптимизировать это в шаг? Почему он уже не оптимизирован таким образом?