fcmpu
Floating Compare Unordered - FC 00 00 00
fcmpu

Instruction Syntax

Mnemonic Format Flags
fcmpu crfD,frA,frB Unordered comparison

Instruction Encoding

1
1
1
1
1
1
F
F
F
0
0
A
A
A
A
A
B
B
B
B
B
0
0
0
0
0
0
0
0
0
0
0

Field Bits Description
Primary Opcode 0-5 111111 (0x3F)
crfD 6-8 Condition Register field destination
Reserved 9-10 00
frA 11-15 Source floating-point register A
frB 16-20 Source floating-point register B
Reserved 21 0
XO 22-30 000000000 (0)
Reserved 31 0

Operation

if (frA) is a NaN or (frB) is a NaN then
  if (frA) is an SNaN or (frB) is an SNaN then
    VXSNAN ← 1
  c ← 0b0001
else
  if (frA) < (frB) then c ← 0b1000
  else if (frA) > (frB) then c ← 0b0100  
  else c ← 0b0010
CR[4×crfD:4×crfD+3] ← c

The contents of floating-point register frA are compared to the contents of floating-point register frB. The result of the comparison is placed into condition register field crfD. The comparison is unordered, meaning that quiet NaNs (QNaNs) do not cause invalid operation exceptions.

Note: Unlike FCMPO, this instruction only signals an invalid operation exception for signaling NaNs (SNaNs), not for quiet NaNs (QNaNs). This makes it suitable for applications that need to handle NaN values gracefully.

Affected Registers

Condition Register (crfD field)

Always affected:

Floating-Point Status and Control Register (FPSCR)

Affected fields:

For more information on floating-point status see Section 2.1.4, "Floating-Point Status and Control Register (FPSCR)," in the PowerPC Microprocessor Family: The Programming Environments manual.

Examples

Basic Unordered Comparison

lfd f1, value_a(r0)        # Load first value
lfd f2, value_b(r0)        # Load second value
fcmpu cr0, f1, f2          # Compare f1 with f2, result in CR0
blt less_than              # Branch if f1 < f2
beq equal                  # Branch if f1 = f2
bgt greater_than           # Branch if f1 > f2
bso either_nan             # Branch if either is NaN

NaN-Safe Maximum Function

# Find maximum, handling NaN gracefully
lfd f1, value1(r0)         # Load first value
lfd f2, value2(r0)         # Load second value
fcmpu cr0, f1, f2          # Unordered compare
bso nan_present            # Branch if either is NaN
bgt f1_is_max              # Branch if f1 > f2
fmr f3, f2                 # f2 is max (or equal), copy to f3
b store_max
f1_is_max:
    fmr f3, f1             # f1 is max, copy to f3
    b store_max
nan_present:
    # Choose first non-NaN value, or default if both NaN
    fcmpu cr0, f1, f1      # Check if f1 is NaN (f1 != f1 if NaN)
    bne f1_is_nan          # Branch if f1 is NaN
    fmr f3, f1             # f1 is valid, use it
    b store_max
f1_is_nan:
    fcmpu cr0, f2, f2      # Check if f2 is NaN
    bne both_nan           # Branch if f2 is also NaN
    fmr f3, f2             # f2 is valid, use it
    b store_max
both_nan:
    lfd f3, default_value(r0) # Both NaN, use default
store_max:
stfd f3, result(r0)        # Store result

Scientific Data Processing

# Process sensor data that may contain invalid readings (NaN)
lfd f1, sensor_reading(r0) # Load sensor reading
lfd f2, threshold(r0)      # Load threshold value
fcmpu cr0, f1, f2          # Compare (unordered to handle NaN)
bso invalid_reading        # Branch if reading is NaN
bgt threshold_exceeded     # Branch if reading > threshold
# Valid reading within threshold
b process_normal_reading
invalid_reading:
    # Handle invalid sensor reading
    b reading_processed
threshold_exceeded:
    # Handle reading above threshold
reading_processed:
process_normal_reading:

Robust Sorting Algorithm

# Sort array elements, placing NaN values at the end
lfdx f1, r3, r4            # Load array[i]
lfdx f2, r3, r5            # Load array[j]
fcmpu cr0, f1, f2          # Unordered compare
bso handle_nan             # Branch if either is NaN
ble no_swap                # Don't swap if array[i] <= array[j]
# Swap elements (both are valid numbers)
stfdx f2, r3, r4           # Store array[j] to position i
stfdx f1, r3, r5           # Store array[i] to position j
b sort_done
handle_nan:
    # Check which value is NaN and handle appropriately
    fcmpu cr0, f1, f1      # Check if f1 is NaN
    bne f1_nan             # Branch if f1 is NaN
    # f2 is NaN, f1 is valid - move f1 to earlier position
    stfdx f1, r3, r5       # Move valid value to later position
    stfdx f2, r3, r4       # Move NaN to earlier position  
    b sort_done
f1_nan:
    # f1 is NaN - it should go to later position (may already be there)
    # Additional logic for NaN placement
no_swap:
sort_done:

Statistical Calculation

# Calculate statistics, skipping NaN values
lfd f1, data_value(r0)     # Load data value
lfd f2, current_sum(r0)    # Load current sum
fcmpu cr0, f1, f1          # Check if data value is NaN
bso skip_nan_value         # Skip if NaN
# Value is valid, add to sum
fadd f2, f2, f1            # Add to sum
stfd f2, current_sum(r0)   # Store updated sum
# Increment count
lwz r3, count(r0)          # Load count
addi r3, r3, 1             # Increment count
stw r3, count(r0)          # Store updated count
b value_processed
skip_nan_value:
    # Increment NaN count for reporting
    lwz r3, nan_count(r0)  # Load NaN count
    addi r3, r3, 1         # Increment NaN count
    stw r3, nan_count(r0)  # Store updated NaN count
value_processed:

Image Processing

# Process pixel values, handling invalid pixels (NaN)
lfd f1, pixel_value(r0)    # Load pixel value
lfd f2, max_brightness(r0) # Load maximum brightness
fcmpu cr0, f1, f1          # Check if pixel is valid (not NaN)
bso invalid_pixel          # Branch if pixel is NaN
fcmpu cr0, f1, f2          # Compare with maximum brightness
bgt clamp_pixel            # Branch if pixel > max brightness
# Pixel is valid and within range
b store_pixel
invalid_pixel:
    lfd f1, default_pixel(r0) # Load default pixel value
    b store_pixel
clamp_pixel:
    fmr f1, f2             # Clamp to maximum brightness
store_pixel:
stfd f1, output_pixel(r0)  # Store processed pixel

Game AI Decision Making

# AI decision based on score comparison, handling invalid scores
lfd f1, player_score(r0)   # Load player score
lfd f2, ai_confidence(r0)  # Load AI confidence level
fcmpu cr0, f1, f1          # Check if player score is valid
bso unknown_player         # Branch if score is NaN
fcmpu cr0, f1, f2          # Compare valid score with confidence
bgt player_winning         # Branch if player score > AI confidence
beq scores_tied            # Branch if scores are equal
# AI is winning
b ai_aggressive_strategy
player_winning:
    # Player is winning
    b ai_defensive_strategy
scores_tied:
    # Scores are tied
    b ai_balanced_strategy
unknown_player:
    # Player score unknown, use cautious strategy
    b ai_cautious_strategy
ai_aggressive_strategy:
ai_defensive_strategy:
ai_balanced_strategy:
ai_cautious_strategy:

Related Instructions

fcmpo, fabs, fsub, fadd, fmr

Back to Index