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:
- LT (bit 0): Set if frA < frB
- GT (bit 1): Set if frA > frB
- EQ (bit 2): Set if frA = frB
- SO (bit 3): Set if either operand is NaN
Floating-Point Status and Control Register (FPSCR)
Affected fields:
- FX (Floating-Point Exception Summary) - only if SNaN encountered
- VXSNAN (Invalid Operation Exception for SNaN) - only if SNaN encountered
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: