fcmpo
Floating Compare Ordered - FC 00 00 40
fcmpo
Instruction Syntax
Mnemonic | Format | Flags |
fcmpo | crfD,frA,frB | Ordered 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
1
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 | 000100000 (32) |
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 VXVC ← 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 ordered, meaning that if either operand is a NaN (Not a Number), appropriate exception flags are set.
Note: This instruction will signal an invalid operation exception if either operand is a signaling NaN (SNaN). For quiet comparisons without exceptions on quiet NaNs, use FCMPU instead.
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)
- VXSNAN (Invalid Operation Exception for SNaN)
- VXVC (Invalid Operation Exception for invalid compare)
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 Floating-Point Comparison
lfd f1, value_a(r0) # Load first value lfd f2, value_b(r0) # Load second value fcmpo 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 unordered # Branch if either is NaN
Finding Maximum Value
# Find maximum of two floating-point values lfd f1, value1(r0) # Load first value lfd f2, value2(r0) # Load second value fcmpo cr0, f1, f2 # Compare values bgt f1_is_max # Branch if f1 > f2 fmr f3, f2 # f2 is max, copy to f3 b store_max f1_is_max: fmr f3, f1 # f1 is max, copy to f3 store_max: stfd f3, maximum(r0) # Store maximum value
Array Sorting Comparison
# Compare array elements for sorting lfdx f1, r3, r4 # Load array[i] lfdx f2, r3, r5 # Load array[j] fcmpo cr0, f1, f2 # Compare elements ble no_swap # Don't swap if array[i] <= array[j] # Swap elements stfdx f2, r3, r4 # Store array[j] to position i stfdx f1, r3, r5 # Store array[i] to position j no_swap:
Range Checking
# Check if value is within range [min, max] lfd f1, input_value(r0) # Load input value lfd f2, min_value(r0) # Load minimum value lfd f3, max_value(r0) # Load maximum value fcmpo cr0, f1, f2 # Compare with minimum blt below_range # Branch if value < min fcmpo cr0, f1, f3 # Compare with maximum bgt above_range # Branch if value > max # Value is within range b in_range below_range: # Handle value below range b range_check_done above_range: # Handle value above range b range_check_done in_range: # Handle value in range range_check_done:
Conditional Assignment
# Assign different values based on comparison lfd f1, score(r0) # Load score lfd f2, threshold(r0) # Load threshold lfd f3, bonus_value(r0) # Load bonus value lfd f4, penalty_value(r0) # Load penalty value fcmpo cr0, f1, f2 # Compare score with threshold bge give_bonus # Branch if score >= threshold fmr f5, f4 # Use penalty value b store_result give_bonus: fmr f5, f3 # Use bonus value store_result: stfd f5, final_value(r0) # Store final value
Error Tolerance Checking
# Check if difference is within tolerance lfd f1, measured(r0) # Load measured value lfd f2, expected(r0) # Load expected value lfd f3, tolerance(r0) # Load tolerance fsub f4, f1, f2 # Calculate difference fabs f4, f4 # Get absolute difference fcmpo cr0, f4, f3 # Compare with tolerance ble within_tolerance # Branch if difference <= tolerance # Difference exceeds tolerance b tolerance_exceeded within_tolerance: # Values are close enough tolerance_exceeded:
Performance Benchmarking
# Compare execution times lfd f1, time1(r0) # Load first execution time lfd f2, time2(r0) # Load second execution time fcmpo cr0, f1, f2 # Compare times blt time1_faster # Branch if time1 < time2 beq times_equal # Branch if times are equal # time2 is faster b record_time2 time1_faster: # time1 is faster b record_time1 times_equal: # Times are equal record_time1: record_time2:
NaN Detection
# Detect and handle NaN values lfd f1, input1(r0) # Load first input lfd f2, input2(r0) # Load second input fcmpo cr0, f1, f2 # Compare values bso nan_detected # Branch if either value is NaN # Both values are valid numbers b values_valid nan_detected: # Handle NaN case # Load default values or signal error values_valid: # Continue with normal processing
Game Physics Collision
# Check if objects are close enough to collide lfd f1, distance(r0) # Load distance between objects lfd f2, collision_radius(r0) # Load collision radius fcmpo cr0, f1, f2 # Compare distance with radius ble collision_detected # Branch if distance <= radius # No collision b no_collision collision_detected: # Handle collision no_collision:
Financial Calculation
# Compare investment returns lfd f1, return_a(r0) # Load return from investment A lfd f2, return_b(r0) # Load return from investment B fcmpo cr0, f1, f2 # Compare returns bgt invest_a_better # Branch if return A > return B beq returns_equal # Branch if returns are equal # Investment B is better b choose_investment_b invest_a_better: # Investment A is better b choose_investment_a returns_equal: # Returns are equal, use other criteria choose_investment_a: choose_investment_b: