我不确定这是否可行,但我想找到一种方法来在x87 FPU寄存器(例如st(0)
)和SSE寄存器(例如xmm1
)之间移动值。上下文是我正在计算存储在内存中的一些浮点值的正弦。我目前的解决方案将这个值加载到st(0)
寄存器中,调用fsin
,将结果存储到一个临时全局变量中,然后将其移动到xmm1
中。有没有一种方法可以直接进入xmm1
寄存器,而不涉及这种内存加载和内存加载?
我知道这不是最优雅的x64汇编,但更广泛的背景是它适用于我正在编写的编译器(它主要使用SSE指令和寄存器,但我看到我需要深入了解x87的三角指令)。
.section .data
outfloatfmt: .asciz "%lf\n"
val: .double 90
tmp: .double 0
sinres: .double 0
.section .text
.extern printf
.global main
main:
pushq %rbp
movq %rsp, %rbp
fld val(%rip) # Load value into st(0)
fsin # For some reason, this computes the sine of zero...
fst tmp(%rip) # Store sine in temp val.
movsd tmp(%rip), %xmm1 # Load tmp sine into xmm1.
movsd %xmm1, sinres(%rip) # THIS is where I want to store the res.
movsd sinres(%rip), %xmm0
leaq outfloatfmt(%rip), %rdi
movq $1, %rax
callq printf
movq %rbp, %rsp
popq %rbp
ret
另一个问题是,我认为st(0)
没有从内存中加载正确的值。在调用fld
之后,我通过GDB检查寄存器,但它总是读取0。如果输入值为90,则应返回1。
1条答案
按热度按时间pbpqsu0x1#
从英特尔手册中可以看出,没有办法直接通过寄存器在x87和MMX之间进行数据移动,即使是在CPU整数寄存器中临时存储浮点数也不行。人们可能希望从某个CPU代开始,将有一条指令将64位“双”浮点存储到长模式64位寄存器或一对32位寄存器中/从长模式64位寄存器或一对32位寄存器中加载64位“双”浮点,作为实际的IEEE格式编码,就像对存储器所做的那样。但幸运的是,大多数具有缓存的CPU将有效地处理堆栈指针附近的存储和加载。