How do you use floating point register comparisons?

Started by wiiztec, December 04, 2011, 03:41:07 AM

Previous topic - Next topic

wiiztec

What's with the cr0 and how do I know if I want an ordered or unordered comparison?
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

megazig

Cr0 is the compare register. All compares use them but they're left off when they are the defaults.

Float compares usually use cr1.

Fcmpu is only signalling instead of comparing based on order

wiiztec

By defaults you mean the regular register comparisons right?

Using the regex search most of the fcmpo's I'm finding use cr0
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

dcx2

The CR register contains 8 fields, cr0-cr7.  cr2, cr3, and cr4 are non-volatile, so if you ever intend to use them, you must push and pop the CR onto the stack before and after you are done.

Integer comparison instructions (e.g. cmpwi) implicitly use cr0 if no cr is specified in the instruction.

Float comparison instructions (e.g. fcmpo) implicitly use cr1 if no cr is specified.

Conditional branch instructions (e.g. bge-) implicitly use cr0.  If using a conditional branch with a float instruction, either explicitly use cr0 with the fcmp[o/u], or explicitly use cr1 with the conditional branch.

Ordered means that a sign-magnitude comparison of float numbers cast as integers will evaluate correctly regardless of what the underlying floats were.  Most CPUs do not have sign-magnitude comparison functions, since they all use two's complement, so in practice this isn't really a concern.

In practice, the difference between fmcpo and fcmpu is minimal.  They should return the same results, except in the case that one of the operands is a NaN.  In this case, remember that a NaN is not ordered (it is Not A Number, so it cannot have an order relative to numbers).  An fcmpo will crash the game if one of the operands is a NaN, unless floating point exceptions are disabled.  An fcmpu will not crash if any of the operands are *quiet* NaNs.  It will still crash if one of the operands is a *signaling* NaN.

A "quiet NaN" is usually generated when you do ambiguous operations.  For instance, if you chose to multiply any number by infinity, the result is ambiguous, and thus becomes a quiet NaN.  Should the quiet NaN be used in subsequent calculations, it will not cause crashing (unless used by an fcmpo, or a float-to-int conversion instruction).

---

If you know that your float values will always be valid, fcmpo is sufficient.  If you want some extra protection in case something goes awry during any previous or subsequent float instructions, you can use fcmpu for some crash protection.

wiiztec

asmwiird doesn't seem to support using fcmpo without specifying the cr
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

dcx2

asmwiird is just a thin wrapper for as, ld, and objcopy.  One of those must not be supporting implicit fcmp's (probably as)

I would probably explicitly use cr0 anyway, so the conditional branch can implicitly use the reg.