Instruction Syntax
Mnemonic | Format | Flags |
fsel | frD,frA,frC,frB | Rc = 0 |
fsel. | frD,frA,frC,frB | Rc = 1 |
Instruction Encoding
Field | Bits | Description |
Primary Opcode | 0-5 | 111111 (0x3F) |
frD | 6-10 | Destination floating-point register |
frA | 11-15 | Source floating-point register A (selector) |
frB | 16-20 | Source floating-point register B (false value) |
frC | 21-25 | Source floating-point register C (true value) |
XO | 26-30 | 10111 (23) |
Rc | 31 | Record Condition Register |
Operation
if frA ≥ 0.0 then frD ← frC else frD ← frB
If the contents of floating-point register frA are greater than or equal to zero, the contents of floating-point register frC are placed into floating-point register frD. Otherwise, the contents of floating-point register frB are placed into floating-point register frD.
Note: This instruction provides a branchless conditional selection based on the sign of a floating-point value. It's particularly useful for avoiding pipeline stalls caused by conditional branches in performance-critical code. NaN values in frA are treated as negative (less than zero).
Affected Registers
Condition Register (CR1 field)
(if Rc = 1)
- Reflects floating-point exception summary and status
Floating-Point Status and Control Register (FPSCR)
Affected fields:
- FPRF (Floating-Point Result Flags) - reflects the selected value
- No exception fields are affected by this instruction
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 Conditional Selection
lfd f1, selector(r0) # Load selector value lfd f2, false_value(r0) # Load value for negative case lfd f3, true_value(r0) # Load value for positive case fsel f4, f1, f3, f2 # f4 = (f1 >= 0.0) ? f3 : f2 stfd f4, result(r0) # Store selected result
Branchless Absolute Value Implementation
# Implement absolute value without branches: |x| lfd f1, input_value(r0) # Load input value fneg f2, f1 # f2 = -input_value fsel f3, f1, f1, f2 # f3 = (input >= 0) ? input : -input stfd f3, abs_result(r0) # Store absolute value
Branchless Maximum Function
# Implement max(a, b) without branches lfd f1, value_a(r0) # Load value A lfd f2, value_b(r0) # Load value B fsub f3, f1, f2 # f3 = a - b fsel f4, f3, f1, f2 # f4 = (a - b >= 0) ? a : b stfd f4, max_result(r0) # Store maximum value
Branchless Minimum Function
# Implement min(a, b) without branches lfd f1, value_a(r0) # Load value A lfd f2, value_b(r0) # Load value B fsub f3, f1, f2 # f3 = a - b fsel f4, f3, f2, f1 # f4 = (a - b >= 0) ? b : a stfd f4, min_result(r0) # Store minimum value
Graphics: Branchless Clipping
# Clip value to [0.0, 1.0] range without branches lfd f1, input_color(r0) # Load color component lfd f2, zero_constant(r0) # Load 0.0 lfd f3, one_constant(r0) # Load 1.0 fsel f4, f1, f1, f2 # f4 = max(input, 0.0) fsub f5, f3, f4 # f5 = 1.0 - f4 fsel f6, f5, f4, f3 # f6 = (1.0 - f4 >= 0) ? f4 : 1.0 stfd f6, clipped_color(r0) # Store clipped color [0.0, 1.0]
Audio Processing: Branchless Signal Gating
# Gate audio signal based on threshold without branches lfd f1, audio_level(r0) # Load audio level lfd f2, threshold(r0) # Load threshold level lfd f3, audio_signal(r0) # Load audio signal lfd f4, zero_constant(r0) # Load 0.0 (silence) fsub f5, f1, f2 # f5 = level - threshold fsel f6, f5, f3, f4 # f6 = (level >= threshold) ? signal : silence stfd f6, gated_audio(r0) # Store gated audio
Physics: Branchless Collision Response
# Select collision response based on impact velocity lfd f1, impact_velocity(r0) # Load impact velocity lfd f2, soft_response(r0) # Load soft collision response lfd f3, hard_response(r0) # Load hard collision response fsel f4, f1, f3, f2 # f4 = (velocity >= 0) ? hard : soft stfd f4, collision_force(r0) # Store collision response force
Machine Learning: Branchless Activation Function
# Implement ReLU activation function: max(0, x) lfd f1, neuron_input(r0) # Load neuron input lfd f2, zero_constant(r0) # Load 0.0 fsel f3, f1, f1, f2 # f3 = (input >= 0) ? input : 0 stfd f3, activated_output(r0) # Store ReLU output
Financial Computing: Branchless Fee Calculation
# Apply fee only if balance is positive lfd f1, account_balance(r0) # Load account balance lfd f2, transaction_fee(r0) # Load transaction fee lfd f3, zero_constant(r0) # Load 0.0 (no fee) fsel f4, f1, f2, f3 # f4 = (balance >= 0) ? fee : 0 stfd f4, applicable_fee(r0) # Store applicable fee
Game AI: Branchless Behavior Selection
# Select AI behavior based on health level lfd f1, health_percentage(r0) # Load health percentage lfd f2, defensive_behavior(r0) # Load defensive behavior weight lfd f3, aggressive_behavior(r0) # Load aggressive behavior weight lfd f4, health_threshold(r0) # Load 50% health threshold fsub f5, f1, f4 # f5 = health - 50% fsel f6, f5, f3, f2 # f6 = (health >= 50%) ? aggressive : defensive stfd f6, ai_behavior(r0) # Store selected behavior
Scientific Computing: Branchless Step Function
# Implement step function: step(edge, x) = (x >= edge) ? 1.0 : 0.0 lfd f1, input_value(r0) # Load input value x lfd f2, edge_value(r0) # Load edge value lfd f3, zero_constant(r0) # Load 0.0 lfd f4, one_constant(r0) # Load 1.0 fsub f5, f1, f2 # f5 = x - edge fsel f6, f5, f4, f3 # f6 = (x >= edge) ? 1.0 : 0.0 stfd f6, step_result(r0) # Store step function result
Real-Time Graphics: Branchless Lighting Calculation
# Apply lighting only to front-facing surfaces lfd f1, surface_normal_dot(r0) # Load surface normal · light direction lfd f2, light_intensity(r0) # Load light intensity lfd f3, zero_constant(r0) # Load 0.0 (no lighting) fsel f4, f1, f2, f3 # f4 = (dot >= 0) ? intensity : 0 stfd f4, final_lighting(r0) # Store final lighting contribution