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: