我一直在尝试从使用的源代码编译gcc 4.x --with-fpmath=387但是我收到了这个错误:"Invalid --with-fpmath=387".我查看了配置并发现它不支持此选项(即使文档仍然提到它作为可能的选项):
case ${with_fpmath} in
avx)
tm_file="${tm_file} i386/avxmath.h"
;;
sse)
tm_file="${tm_file} i386/ssemath.h"
;;
*)
echo "Invalid --with-fpmath=$with_fpmath" 1>&2
exit 1
Run Code Online (Sandbox Code Playgroud)
基本上,我开始了这一切,因为我需要为旧的目标平台提供可执行文件(事实上,它是一个旧的Celeron,但没有任何SSE2指令显然由libfdc ++由DEFAULT使用).可执行文件在第一条指令(movq XMM0,...)崩溃,该指令来自libstdc ++中的复制例程,带有"非法指令"消息.有什么方法可以解决这个问题吗?我需要使用相当新的g ++才能移植现有的代码库.
我想知道是否可以从旧版本提供这些头文件/源代码以支持常规x87指令,以便不引用SSE指令?
更新:请注意我在谈论编译的libstdc ++在目标代码中有SSE2指令,所以问题不在于gcc命令行参数.无论我在编译代码时向gcc提供什么,它都将与已经内置SSE2指令的libstdc ++链接.
真正的答案是在编译GCC时不使用任何 --with-fpmath开关.我对配置脚本switch语句感到困惑,认为它只支持sse或avx,而实际上是默认值(此开关中未提及的是"387").因此,请确保在运行configure时不使用--with-fpmath.我没有它重新编译GCC,它现在工作正常.
谢谢.
在我尝试为x86平台上的32位Linux编写反汇编程序时,我遇到了一个问题.当我使用以下方法拆卸简单的ELF-32可执行文件时,我看到了以下操作码序列objdump:
dc 82 04 08 0d 00 faddl 0xd0804(%edx)
Run Code Online (Sandbox Code Playgroud)
但是当我查看英特尔手册时,我没有看到对应的操作码.该fadd指令以0xDC开始,但它需要一个m64fp操作数,即"内存中的内存四字操作数".
现在,这是否意味着操作数是64位地址(这意味着该fadd指令是64位指令,但不以REX字节作为前缀),或者它只是一个32位地址指向到四字(64位)?
我在这里遗漏了一些微不足道的东西,还是我对编码x86指令的理解错了?
我在程序中有这样的指令:
FSTENV (28-BYTE) PTR SS:[ESP-1C]
Run Code Online (Sandbox Code Playgroud)
它有什么作用?
它使用和更新哪些寄存器?
谢谢你!
我正在尝试在 x87 中计算函数 e^x(x 是单精度浮点数)。为了实现这一点,我使用泰勒级数(作为提醒:e^x = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n !)
当我使用 x87 时,我可以计算扩展精度(80 位而不是单精度 32 位)的所有值。
到目前为止,我的认识是:我在 FPU 的两个单独寄存器中拥有被加数和总和(以及其他一些不太重要的东西)。我有一个循环,它不断更新被加数并将其添加到总和中。所以在模糊的伪代码中:
loop:
;update my summand
n = n + 1
summand = summand / n
summand = summand * x
;add the summand to the total sum
sum = sum + summand
Run Code Online (Sandbox Code Playgroud)
我现在的问题是循环的退出条件。我想以一种方式设计它,一旦将被加数添加到总和不会影响单精度总和的值,它就会退出循环,即使我正在找出实现这种退出条件的艰难方法非常复杂,占用大量指令 -> 计算时间。
到目前为止,我唯一的好主意是: 1.:通过 FXTRACT 获取总和和被加数的指数。如果 (exp(sum) - exp(summand)) > 23,被加数将不再影响单精度中的位表示(因为单精度中的尾数有 23 位)--> 所以退出。2.:将被加数与0比较,如果是0显然也不会影响结果了。
我的问题是,对于现有条件,是否有人会比我有更有效的想法?
我想知道为什么FYL2XP1x86 架构上的指令精确地计算数学公式 y · log 2 ( x + 1)。
这个公式有什么特别之处?
我们正在编写一个模拟器,并想知道对于给定的FPU状态,是运行FPU指令后FPU确定性的状态,例如.FDIV?
有许多Intel兼容的CPU架构,它们实现了x87指令集.在测试FPU仿真的正确性时,我们应该依赖于生成的CPU状态吗?
不同的实现是围绕/计算不同的吗?
我写了一个这样的矢量结构:
struct vector {
float x1, x2, x3, x4;
};
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个函数,它使用向量使用内联汇编执行一些操作:
struct vector *adding(const struct vector v1[], const struct vector v2[], int size) {
struct vector vec[size];
int i;
for(i = 0; i < size; i++) {
asm(
"FLDL %4 \n" //v1.x1
"FADDL %8 \n" //v2.x1
"FSTL %0 \n"
"FLDL %5 \n" //v1.x2
"FADDL %9 \n" //v2.x2
"FSTL %1 \n"
"FLDL %6 \n" //v1.x3
"FADDL %10 \n" //v2.x3
"FSTL %2 \n"
"FLDL %7 \n" //v1.x4
"FADDL %11 \n" //v2.x4
"FSTL …Run Code Online (Sandbox Code Playgroud) section .data
qVar1: dq 1
section .bss
var28: resb 28
section .text
_main:
; Use an MMX instruction
movq mm0, [qVar1] ; Move quadword from r/m64 to mm.
; Read Tag Word
fstenv [var28]
mov ax, [var28 + 8] ; move the Tag Word to ax
Run Code Online (Sandbox Code Playgroud)
这一刻ax是0101 0101 0101 0110
但是从英特尔手册,第9.5.1节MMX指令和x87 FPU标签字,我引用:
在每个MMX指令之后,整个x87 FPU标记字被设置为有效(00B).
那么为什么ax不是全零呢?
ceil、floor 在 x86 中的等价物是什么?我无法特别谷歌相应的说明。等效指令不一定是一条指令,尽管一条指令是优选的。
Masm 允许在指令前使用不同的 cpu 组合,但某些组合不能正确检测需要等待前缀的协处理器指令,并且在需要等待前缀时将导致没有等待前缀。以下组合将导致它们之后的任何数学协处理器指令没有等待前缀:
Run Code Online (Sandbox Code Playgroud)example 1: .386 .8087 ;now enter math coprocessor instruction example 2: .286 .8087 ;now enter math coprocessor instruction example 3: .386 .287 ;now enter math coprocessor instruction
如果然后使用数学协处理器指令,则不会创建等待前缀(通常由 MASM 创建)。以下是在应该有等待前缀时不会有等待前缀的说明:
FRSTOR、FFREE、FDECSTP、FINCSTP、FLDENV、FLDCW FLD、FST、FSTP、FXCH、FLDZ、FLD1、FLDPI、FLDL2E、FLDL2T、FLDLG2、FLDLN2、FILD、FIST、FISTP、FBLD、FBSTP、FCOM、FCOMP、FCOMPP、FICOM ,FICOMP,FXAM,FADD,FADDP,FMUL,FMULP,FSUB,FSUBP,FSUBR,FSUBRP,FDIV,FDIVP,FDIVR,FDIVRP,FABS,FCHS,FSQRT,FRNDINT,FIADD,FIMUL,FISUB,FISUBR,FIDIV,FIDIVR,FPTAN ,FPATAN,F2XM1,FSCALE, FYL2X,FYL2XP1,FPREM,FPREM1,FXTRACT,FSETPM 和 FNOP
这些指令不受影响:
FCLEX、FNCLEX、FSAVE、FNSAVE、FENI、FNENI、FDISI、FNDISI、FSTENV、FNSTENV、FINIT、FNINIT、FSTSW、FNSTSW、FSTCW 和 FNSTCW
这是一个错误吗?我没有找到提到这种行为的文档。我没有更高版本的 MASM 来查看是否已修复。我的版本是 masm v6。