I want to truncate a floating-point number in one of the xmm
registers to a 64-bit register, as stated by the title. Below I am dividing 15.9 by 4.95. I'm printing this out and I see that result is correct (3.212121). However, when using cvtss2si
to truncate this, rdi
is becoming zero in some way. I have no idea why. Why does this not truncate properly when I am expecting 3 as a result? I am on macOS assembling with Clang.
.global _main
.text
_main:
movsd xmm0, qword ptr [dividend + rip]
divsd xmm0, qword ptr [divisor + rip]
movsd [result + rip], xmm0
lea rdi, [frm + rip]
movsd xmm0, qword ptr [result + rip]
mov al, 1
and rsp, -16
call _printf
cvtss2si rdi, xmm0 # expecting 3, is 0
mov rax, 0x2000001
syscall
.data
dividend:
.quad 15.9
divisor:
.quad 4.95
result:
.quad 0.0
frm:
.asciz "%f\n"
ss
is scalar single precision. You're converting the low 32-bits of the double
's mantissa. As a binary32 bit-pattern, that represents a small number or exactly zero. Also, if you want to truncate instead of round to nearest, use the truncating conversion (an extra t
). cvttsd2si rdi, xmm0
https://www.felixcloutier.com/x86/cvttsd2si.
Of course, xmm registers are call-clobbered in x86-64 System V, so it makes no sense to read XMM0 right after printf returns.