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: