Instruction Syntax
Mnemonic | Format | Flags |
fnmsubs | frD,frA,frC,frB | Rc = 0 |
fnmsubs. | frD,frA,frC,frB | Rc = 1 |
Instruction Encoding
Field | Bits | Description |
Primary Opcode | 0-5 | 111011 (0x3B) |
frD | 6-10 | Destination floating-point register |
frA | 11-15 | Source floating-point register A (multiplicand) |
frB | 16-20 | Source floating-point register B (subtrahend) |
frC | 21-25 | Source floating-point register C (multiplier) |
XO | 26-30 | 11110 (30) |
Rc | 31 | Record Condition Register |
Operation
frD ← -SINGLE((frA × frC) - frB)
The contents of floating-point register frA are multiplied by the contents of floating-point register frC. The contents of floating-point register frB are then subtracted from this intermediate product. The result is rounded to single-precision, then negated, and placed into floating-point register frD.
Note: This is a fused negative multiply-subtract operation optimized for single-precision. The intermediate product (frA × frC) is computed to infinite precision, frB is subtracted from it, the result is rounded to single-precision format, and then negated. This provides both the accuracy benefits of fused multiply-subtract and the performance advantages of single-precision arithmetic. The result is stored in double-precision format in the FPR.
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)
- FX (Floating-Point Exception Summary)
- OX (Overflow Exception)
- UX (Underflow Exception)
- XX (Inexact Exception)
- VXISI (Invalid Operation Exception for ∞ - ∞)
- VXIMZ (Invalid Operation Exception for 0 × ∞)
- FR (Fraction Rounded)
- FI (Fraction Inexact)
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 Single-Precision Negative Multiply-Subtract
lfs f1, multiplicand(r0) # Load single-precision multiplicand lfs f2, subtrahend(r0) # Load single-precision subtrahend lfs f3, multiplier(r0) # Load single-precision multiplier fnmsubs f4, f1, f3, f2 # f4 = -SINGLE((f1 × f3) - f2) stfs f4, result(r0) # Store single-precision result
3D Graphics: Inverted Single-Precision Vector Difference
# Calculate inverted scaled difference: result = -(scale × vector1 - vector2) lfs f1, scale_factor(r0) # Load scale factor lfs f2, vector1_x(r0) # Load vector1 X component lfs f3, vector2_x(r0) # Load vector2 X component fnmsubs f4, f1, f2, f3 # f4 = -(scale × vector1_x - vector2_x) stfs f4, inverted_diff_x(r0) # Store inverted difference X
Audio Processing: Inverted Single-Precision Echo Cancellation
# Inverted echo cancellation: output = -(gain × input - echo_estimate) lfs f1, gain_factor(r0) # Load gain factor lfs f2, input_signal(r0) # Load input signal lfs f3, echo_estimate(r0) # Load echo estimate fnmsubs f4, f1, f2, f3 # f4 = -(gain × input - echo_estimate) stfs f4, inverted_clean(r0) # Store inverted clean signal
Game Physics: Inverted Single-Precision Momentum
# Calculate inverted momentum difference: result = -(mass × velocity - impulse) lfs f1, object_mass(r0) # Load object mass lfs f2, velocity(r0) # Load velocity lfs f3, impulse(r0) # Load impulse fnmsubs f4, f1, f2, f3 # f4 = -(mass × velocity - impulse) stfs f4, inverted_momentum(r0) # Store inverted momentum change
Computer Graphics: Inverted Single-Precision Lighting Difference
# Inverted lighting difference: result = -(strength × dot_product - shadow) lfs f1, light_strength(r0) # Load light strength lfs f2, dot_product(r0) # Load surface normal · light direction lfs f3, shadow_factor(r0) # Load shadow factor fnmsubs f4, f1, f2, f3 # f4 = -(strength × dot_product - shadow) stfs f4, inverted_light(r0) # Store inverted lighting
Signal Processing: Inverted Single-Precision Noise Removal
# Inverted noise removal: output = -(signal × enhancement - noise) lfs f1, enhancement_gain(r0) # Load enhancement gain lfs f2, noisy_signal(r0) # Load noisy signal lfs f3, noise_profile(r0) # Load noise profile fnmsubs f4, f1, f2, f3 # f4 = -(enhancement × signal - noise) stfs f4, inverted_clean(r0) # Store inverted clean signal
Machine Learning: Inverted Single-Precision Gradient
# Inverted gradient calculation: result = -(learning_rate × gradient - momentum) lfs f1, learning_rate(r0) # Load learning rate lfs f2, gradient(r0) # Load gradient lfs f3, momentum_term(r0) # Load momentum term fnmsubs f4, f1, f2, f3 # f4 = -(learning_rate × gradient - momentum) stfs f4, inverted_update(r0) # Store inverted weight update
Financial Computing: Inverted Single-Precision Loss
# Inverted profit calculation: loss = -(price × quantity - cost) lfs f1, unit_price(r0) # Load unit price lfs f2, quantity(r0) # Load quantity sold lfs f3, total_cost(r0) # Load total cost fnmsubs f4, f1, f2, f3 # f4 = -(price × quantity - cost) stfs f4, inverted_profit(r0) # Store inverted profit (loss)
Real-Time Audio: Inverted Single-Precision Filter Response
# Inverted filter response: output = -(gain × input - feedback) lfs f1, filter_gain(r0) # Load filter gain lfs f2, input_sample(r0) # Load input sample lfs f3, feedback_signal(r0) # Load feedback signal fnmsubs f4, f1, f2, f3 # f4 = -(gain × input - feedback) stfs f4, inverted_filter(r0) # Store inverted filter output
Game AI: Inverted Single-Precision Cost Function
# Inverted pathfinding cost: cost = -(distance × difficulty - bonus) lfs f1, difficulty_factor(r0) # Load difficulty factor lfs f2, path_distance(r0) # Load path distance lfs f3, terrain_bonus(r0) # Load terrain bonus fnmsubs f4, f1, f2, f3 # f4 = -(difficulty × distance - bonus) stfs f4, inverted_cost(r0) # Store inverted pathfinding cost
Physics Simulation: Inverted Single-Precision Force Balance
# Inverted force balance: result = -(applied_force × multiplier - resistance) lfs f1, force_multiplier(r0) # Load force multiplier lfs f2, applied_force(r0) # Load applied force lfs f3, resistance(r0) # Load resistance force fnmsubs f4, f1, f2, f3 # f4 = -(applied_force × multiplier - resistance) stfs f4, inverted_net_force(r0) # Store inverted net force