为什么x86 FP像无符号整数一样比较集CF,而不使用有符号条件? [英] Why do x86 FP compares set CF like unsigned integers, instead of using signed conditions?

查看:192
本文介绍了为什么x86 FP像无符号整数一样比较集CF,而不使用有符号条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

《英特尔指令参考》中为COMISD指令提供了以下文档:

The following documentation is provided in the Intel Instruction Reference for the COMISD instruction:

比较低位的双精度浮点值 操作数1(第一个操作数)和操作数2(第二个操作数)的四元, 并根据以下内容在EFLAGS寄存器中设置ZFPFCF标志 结果(无序,大于,小于或等于).

Compares the double-precision floating-point values in the low quadwords of operand 1 (first operand) and operand 2 (second operand), and sets the ZF, PF, and CF flags in the EFLAGS register according to the result (unordered, greater than, less than, or equal).

CF的标志点在这里并不清楚,因为它与对无符号整数的算术运算有关.相反,文档关注的是按定义签名的浮点.我进行了一些实验,例如

The CF's flag point is not really clear here since it is related to arithmetic operations on unsigned integers. By contrast, the documentation is concerned about floating point which are signed by definition. I ran a few experiments, like

mov rax, 0x123
movq xmm0, rax

mov rax, 0x124
movq xmm1, rax

ucomisd xmm0, xmm1 ;CF is set here like if
                    ;we would compare uints 0x123 and 0x124

因此,当将操作数设置为双精度浮点时,将进位标志设置为1时,指令会将操作数视为无符号整数吗?

So the instruction treats the operands as unsigned integers when setting Carry Flag up while the operands are double-precision floating points?

在我看来,这有点奇怪.

To me it looks a bit strange.

推荐答案

现代x86 SSE/AVX标量FP与原始8086 + 8087相同地比较集合EFLAGS
fcom + fstsw ax 1 + sahf.

Modern x86 SSE/AVX scalar FP compares set EFLAGS the same way as original 8086 + 8087
fcom + fstsw ax 1 + sahf.

  • fcom since 8086
  • fcomi new in PPro, sets EFLAGS directly
  • [u]comis[sd] new in SSE/SSE2, also sets EFLAGS directly.

排除了jcc/setcc/>),低于"(<)和等于"(==)条件>/fcmovcc都具有适当的语义. (以及它们的组合,例如jae.)

After ruling out "unordered", the "above" (>), "below" (<), and "equal" (==) conditions for jcc/setcc/cmovcc/fcmovcc all have the appropriate semantic meaning. (And combinations of them like jae.)

保持相同的标志设置,使程序员和编译器开发人员可以更轻松地放入标量SSE代码来代替标量x87代码,而不必重做关于无序比较的任何逻辑(PF = ZF = CF = 1)会参加.像ja(CF == 0)这样的窍门仅用于>(不适用于无序,相等或以下),仍然可以在相同的分支上相同地工作.

Keeping the flag-setting the same made it easier for programmers and compiler-developers to drop in scalar SSE code, in place of scalar x87 code, without having to redo any logic about which way unordered compares (PF=ZF=CF=1) would go. Tricks like ja (CF==0) being taken only for > (not for unordered, equal, or below) still work identically with the same branches.

请参见 http://www.ray.masmcode.com/tutorial/fpuchap7. htm 用于x87 FP比较.也相关: x86汇编器:浮点比较,以获取有关标志设置以及如何设置标志的更多信息有时可以在没有jp的情况下走开,以排除无序的情况.

See http://www.ray.masmcode.com/tutorial/fpuchap7.htm for x87 FP comparisons. Also related: x86 assembler: floating point compare for more about flag-setting and how you can sometimes get away without a jp to rule out the unordered case.

请注意,如 cmppd cmpsd这样的打包比较指令会产生掩码仍然使用lt小于其比较谓词的名称. (自AVX起,有更详细的谓词名称,如LT_OQ(QNaN也不例外)vs. LT_OS(QNaN具有其通常的作用)与NLT_US(无序:当比较无序时也是如此)由于它们必须从每个打包的比较中产生0/1的结果,因此这些SIMD比较指令不仅需要进行比较,还需要单个谓词来进行检查.

Note that the packed-compare instructions like cmppd and cmpsd that produce a mask still use lt for less than in the names of their comparison predicates. (Since AVX, there are more detailed predicate names like LT_OQ (QNaN isn't an exception) vs. LT_OS (QNaN has its usual effect) vs. NLT_US (Unordered: also true when the comparison is unordered). Since they have to produce a 0/1 result from each packed comparison, those SIMD compare instructions need a single predicate to check as well as just doing a compare.

此外,无符号条件(CF)允许进行更多优化.因此,更改为已签署的条件会更糟.

Also, unsigned conditions (CF) allow more optimizations. So changing to signed conditions would have been worse.

x86使用CF的指令要多于使用其他标志的指令.例如,您可以使用ucomisd/adc eax, 0进行tmp += (x > 10).如果SSE/SSE2已决定设置SF(并清除OF),则需要sets或其他setcc来提供add指令.

x86 has more instructions that do things with CF than with any other flag. For example, you can do tmp += (x > 10) with ucomisd / adc eax, 0. If SSE/SSE2 had decided to set SF (and clearing OF), you'd need sets or other setcc to feed an add instruction.

OF在标志的低8位之外,因此sahf无法设置.设置整个FLAGS寄存器的popf可以设置或清除其他无条件的FLAGS,例如IF(允许中断)或TF(每条指令后的单步陷阱).此外,由于修改SP,使用起来通常不太方便.

OF is outside the low 8 bits of FLAGS so sahf can't set it. And popf to set the whole FLAGS register could set or clear other non-condition FLAGS like IF (interrupts enabled) or TF (single-step trap after every instruction). Plus being generally less convenient to use because of modifying SP.

签名标志条件基于SF!=OFSF==OF,因此原始8086 FP分支机制不可能使用签名条件.相反,他们将FP状态字中的C0,C2和C3位与FLAGS中的CF,PF和ZF对齐. 此答案具有ASCII艺术图.

Signed flag-conditions are based on SF!=OF or SF==OF, so it was impossible for the original 8086 FP branching mechanism to have used signed conditions. Instead, they lined up the C0, C2, and C3 bits in the FP status word with CF, PF, and ZF in FLAGS. This answer has an ASCII-art diagram.

脚注1 :根据fstsw ax是286中的新功能="nofollow noreferrer"> NASM的附录B .在 actual 8086 + 8087代码中,您将使用诸如fstsw [bp-2]/mov ax, [bp-2]/sahf之类的东西或任何您想使用的临时空间.

Footnote 1: Actually fstsw ax was new in 286, according to NASM's appendix B. In actual 8086+8087 code, you'd use something like fstsw [bp-2] / mov ax, [bp-2] / sahf or whatever scratch space you wanted to use.

因此指令将操作数视为无符号整数

So the instruction treats the operands as unsigned integers

不,绝对不是.它们被解释为符号/幅度IEEE binary64 FP位模式.

No, definitely not. They are interpreted as sign/magnitude IEEE binary64 FP bit-patterns.

无符号整数比较对于负浮点数将给出不同的结果:高位设置=>高无符号整数,但表示FP负值.

Unsigned integer comparison would give a different result for negative floating point numbers: High bit set => higher unsigned integer, but represents a negative FP value.

设置高位后,0x8...40x8...3上方是无符号整数,但作为FP位模式,它表示一个更大的负数(更低).

With the high bit set, 0x8...4 is unsigned-integer above 0x8...3, but as an FP bit pattern, it represents a more-negative (lower) number.

在将它们用于FP时,无需考虑上方"/下方"条件的无符号"关联.这就是x86称为测试进位标记的条件.

Forget about the "unsigned" association of the "above" / "below" conditions when using them for FP. That's just what x86 calls the conditions that test the carry flag.

FP比较通过与实际整数减法完全不同的机制设置进位标志.

这篇关于为什么x86 FP像无符号整数一样比较集CF,而不使用有符号条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆