I need to convert both 32-bit and 64-bit unsigned integers into floating-point values in xmm registers. There are x86 instructions to convert signed integer
Shamelessly using Janus answer as a template (after all I really like C++):
Generate with gcc -march=native -O3
on a i7, so this is with up to and including -mavx
.
uint2float
and vice versa are as expected, the long conversions just have a special case for numbers greater than 263-1.
0000000000000000 :
0: 48 85 ff test %rdi,%rdi
3: 78 0b js 10
5: c4 e1 fb 2a c7 vcvtsi2sd %rdi,%xmm0,%xmm0
a: c3 retq
b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
10: 48 89 f8 mov %rdi,%rax
13: 83 e7 01 and $0x1,%edi
16: 48 d1 e8 shr %rax
19: 48 09 f8 or %rdi,%rax
1c: c4 e1 fb 2a c0 vcvtsi2sd %rax,%xmm0,%xmm0
21: c5 fb 58 c0 vaddsd %xmm0,%xmm0,%xmm0
25: c3 retq
0000000000000030 :
30: 48 85 ff test %rdi,%rdi
33: 78 0b js 40
35: c4 e1 fa 2a c7 vcvtsi2ss %rdi,%xmm0,%xmm0
3a: c3 retq
3b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
40: 48 89 f8 mov %rdi,%rax
43: 83 e7 01 and $0x1,%edi
46: 48 d1 e8 shr %rax
49: 48 09 f8 or %rdi,%rax
4c: c4 e1 fa 2a c0 vcvtsi2ss %rax,%xmm0,%xmm0
51: c5 fa 58 c0 vaddss %xmm0,%xmm0,%xmm0
55: c3 retq
0000000000000060 :
60: 89 ff mov %edi,%edi
62: c4 e1 fb 2a c7 vcvtsi2sd %rdi,%xmm0,%xmm0
67: c3 retq
0000000000000070 :
70: 89 ff mov %edi,%edi
72: c4 e1 fa 2a c7 vcvtsi2ss %rdi,%xmm0,%xmm0
77: c3 retq