Intel x86_64 程序集,如何在 x87 和 SSE2 之间移动? (计算双的反正切)
Intel x86_64 assembly, How to move between x87 and SSE2? (calculating arctangent of double)
我尝试计算保存在 xmm 寄存器中的双精度浮点值的反正切值。使用普通的浮点指针,可以使用旧的 x87 指令 FPATAN,但是我如何使用 double 来做到这一点?
您可以仍然将数据从 xmm 复制到 x87 以使用像 fpatan
这样的指令,但通常您应该调用数学库函数。 (fpatan
太慢了,用许多简单的指令替换它仍然很好。)维基百科建议查看 Netlib 以获取可自由再分发的 C 实现。 (显然,最简单的方法是在您使用的任何系统上调用 libm 中的函数。)
如果你打算这样做,不要为你反弹的内存使用静态存储;在堆栈上使用临时文件。
另请注意 fpatan
takes 2 inputs, because it implements the atan2
library function,根据两个输入的符号在适当的象限中给出结果。
; assuming you did sub rsp, 24 or something earlier in your function
movsd [rsp], xmm1
fld qword [rsp] ; st0 = xmm1
movsd [rsp], xmm0
fld qword [rsp] ; st0 = xmm0, st1 = xmm1
fpatan ; st0 = arctan(xmm1/xmm0)
fstp qword [rsp] ; x87 stack is empty again
movsd xmm0, [rsp] ; xmm0 = arctan(xmm1/xmm0)
; and then add rsp, 24 at some point before returning
我尝试计算保存在 xmm 寄存器中的双精度浮点值的反正切值。使用普通的浮点指针,可以使用旧的 x87 指令 FPATAN,但是我如何使用 double 来做到这一点?
您可以仍然将数据从 xmm 复制到 x87 以使用像 fpatan
这样的指令,但通常您应该调用数学库函数。 (fpatan
太慢了,用许多简单的指令替换它仍然很好。)维基百科建议查看 Netlib 以获取可自由再分发的 C 实现。 (显然,最简单的方法是在您使用的任何系统上调用 libm 中的函数。)
如果你打算这样做,不要为你反弹的内存使用静态存储;在堆栈上使用临时文件。
另请注意 fpatan
takes 2 inputs, because it implements the atan2
library function,根据两个输入的符号在适当的象限中给出结果。
; assuming you did sub rsp, 24 or something earlier in your function
movsd [rsp], xmm1
fld qword [rsp] ; st0 = xmm1
movsd [rsp], xmm0
fld qword [rsp] ; st0 = xmm0, st1 = xmm1
fpatan ; st0 = arctan(xmm1/xmm0)
fstp qword [rsp] ; x87 stack is empty again
movsd xmm0, [rsp] ; xmm0 = arctan(xmm1/xmm0)
; and then add rsp, 24 at some point before returning