声明中:
divsd xmm0,xmm1
剩下的存储在哪里? xmm寄存器是否有余数寄存器,如整数寄存器?我应该在x87指令中使用FPREM吗?
据我所知,英特尔手册在这个问题上没有提及,很多研究都没有提供有用的答案。
答案 0 :(得分:1)
DIVSD
处理单个浮点,因此不会返回余数。相反,它会为该类型的浮点数计算尽可能多的小数。
来自英特尔文档:
# DIVSD (128-bit Legacy SSE version)
DEST[63:0] ← DEST[63:0] / SRC[63:0]
DEST[MAX_VL-1:64] (Unmodified)
请注意,这与FDIV
指令相同。
当然,您可以使用通常的方法计算余数,方法是将结果转换为整数,再乘以,然后从原始数字中减去。
像这样的东西(UNTESTED!AT& T语法)
; inputs: xmm1 divisor, xmm2 dividend
MOVQ xmm3, xmm2 ; xmm3 ← xmm2
DIVPS xmm2, xmm1 ; xmm2 ← xmm2 ÷ xmm1
CVTPS2DQ xmm3, xmm2 ; xmm3 ← integers of xmm2
MULPS xmm3, xmm1 ; xmm3 ← xmm3 × xmm1
MOVQ xmm4, xmm2 ; xmm4 ← xmm2
SUBPS xmm4, xmm3 ; xmm3 ← xmm3 - xmm2
; xmm2 = xmm2 ÷ xmm1
; xmm4 = remainder (mathematically: frac(xmm2) × xmm1)
使用FPREM
时可能遇到的问题是您无法使用浮点单元和MMX寄存器混合代码。他们最终都使用相同的寄存器,但不同。
有一些关于该问题的文档。如果你不使用MMX寄存器,你可以没事。
来源:Vol。 1 11-31 - 使用流式SIMD扩展2进行编程(SSE2)
11.6.7 SSE / SSE2指令与x87 FPU和MMX指令的交互
XMM寄存器和x87 FPU和MMX寄存器代表单独的执行环境,在同一代码模块中执行SSE,SSE2,MMX和x87 FPU指令时或在混合包含这些指令的代码模块时具有某些分支: / p>
•那些只在XMM寄存器上运行的SSE和SSE2指令(例如压缩和标量浮点指令和128位SIMD整数指令)在同一条指令流中使用64位整数或x87 FPU指令而没有任何指令限制。例如,应用程序可以执行
XMM寄存器中的大部分浮点计算,使用压缩和标量浮点指令,同时使用x87 FPU执行三角函数和其他超越计算。同样,应用程序可以无限制地一起执行打包的64位和128位SIMD整数操作。
•在MMX寄存器上运行的那些SSE和SSE2指令(例如CVTPS2PI,CVTTPS2PI,CVTPI2PS,CVTPD2PI,CVTTPD2PI,CVTPI2PD,MOVDQ2Q,MOVQ2DQ,PADDQ和PSUBQ指令)也可以在与指令流相同的指令流中执行。但是,这里的64位SIMD整数或x87 FPU指令受限于同时使用MMX技术和x87 FPU指令,其中包括:
- 从x87 FPU到MMX技术指令或在MMX寄存器上运行的SSE或SSE2指令的转换之前应先保存x87 FPU的状态。
- 从MMX技术指令或从MMX寄存器操作的SSE或SSE2指令到x87 FPU指令的转换之前,应先执行EMMS指令。
由于您有很多XMM / YMM / ZMM寄存器,因此在SSE / AVX中执行此类操作通常是值得的。另一方面,FPU使用的堆栈在装配时更难处理。