Instruction Syntax
Mnemonic | Format | Flags |
fnmsub | frD,frA,frC,frB | Rc = 0 |
fnmsub. | 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 (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 ← -((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 then negated and placed into floating-point register frD.
Note: This is a fused negative multiply-subtract operation. The intermediate product (frA × frC) is computed to infinite precision, frB is subtracted from it, and then the final result is negated. Only one rounding operation occurs, at the end, which provides higher accuracy than separate operations. This instruction is particularly useful in certain signal processing and mathematical algorithms.
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 Negative Multiply-Subtract Operation
lfd f1, multiplicand(r0) # Load multiplicand (A) lfd f2, subtrahend(r0) # Load subtrahend (B) lfd f3, multiplier(r0) # Load multiplier (C) fnmsub f4, f1, f3, f2 # f4 = -((f1 × f3) - f2) stfd f4, result(r0) # Store result
Signal Processing: Inverted Difference Filter
# Implement inverted difference filter: output = -(coeff × input - reference) lfd f1, filter_coeff(r0) # Load filter coefficient lfd f2, input_signal(r0) # Load input signal lfd f3, reference_level(r0) # Load reference level fnmsub f4, f1, f2, f3 # f4 = -(coeff × input - reference) stfd f4, inverted_diff(r0) # Store inverted difference
Physics: Negative Spring-Damper System
# Calculate negative restoring force: F = -(k×x - b×v) # Where k is spring constant, x is displacement, b is damping, v is velocity lfd f1, spring_constant(r0) # Load spring constant k lfd f2, displacement(r0) # Load displacement x lfd f3, damping_coeff(r0) # Load damping coefficient b lfd f4, velocity(r0) # Load velocity v fnmsub f5, f1, f2, f0 # f5 = -(k × x - 0) = -kx fmsub f6, f3, f4, f5 # f6 = b×v - (-kx) = bv + kx (temporary) fneg f7, f6 # f7 = -(bv + kx) = -bv - kx # Alternative: direct calculation fnmsub f8, f1, f2, f3 # f8 = -(k×x - b×v) (if v represents negative damping) stfd f8, restoring_force(r0) # Store negative restoring force
Graphics: Inverse Color Blending
# Calculate inverse blend: result = -(src × alpha - dst) lfd f1, src_color(r0) # Load source color component lfd f2, alpha_value(r0) # Load alpha value lfd f3, dst_color(r0) # Load destination color component fnmsub f4, f1, f2, f3 # f4 = -(src × alpha - dst) stfd f4, inverse_blend(r0) # Store inverse blended color
Audio Processing: Inverted Echo Cancellation
# Echo cancellation: output = -(echo_gain × delayed - original) lfd f1, echo_gain(r0) # Load echo gain factor lfd f2, delayed_signal(r0) # Load delayed signal lfd f3, original_signal(r0) # Load original signal fnmsub f4, f1, f2, f3 # f4 = -(echo_gain × delayed - original) stfd f4, cancelled_echo(r0) # Store echo-cancelled signal
Mathematical: Negative Difference of Products
# Calculate -(a×b - c): negative difference of products lfd f1, value_a(r0) # Load a lfd f2, value_b(r0) # Load b lfd f3, value_c(r0) # Load c fnmsub f4, f1, f2, f3 # f4 = -(a × b - c) stfd f4, neg_diff_prod(r0) # Store negative difference
Control Systems: Inverted Error Signal
# Generate inverted error: error = -(Kp × measurement - setpoint) lfd f1, proportional_gain(r0) # Load Kp gain lfd f2, measurement(r0) # Load measured value lfd f3, setpoint(r0) # Load desired setpoint fnmsub f4, f1, f2, f3 # f4 = -(Kp × measurement - setpoint) stfd f4, inverted_error(r0) # Store inverted error signal
Game Physics: Negative Momentum Transfer
# Calculate negative momentum transfer: F = -(m×v - impulse) lfd f1, mass(r0) # Load mass lfd f2, velocity(r0) # Load velocity lfd f3, impulse(r0) # Load impulse fnmsub f4, f1, f2, f3 # f4 = -(mass × velocity - impulse) stfd f4, neg_momentum(r0) # Store negative momentum transfer
Financial Analysis: Negative Profit Margin
# Calculate negative profit: loss = -(price × quantity - cost) lfd f1, unit_price(r0) # Load unit price lfd f2, quantity(r0) # Load quantity sold lfd f3, total_cost(r0) # Load total cost fnmsub f4, f1, f2, f3 # f4 = -(price × quantity - cost) stfd f4, net_loss(r0) # Store net loss (negative profit)
Scientific Computing: Negative Residual
# Calculate negative residual: res = -(predicted × weight - observed) lfd f1, predicted_value(r0) # Load predicted value lfd f2, weight_factor(r0) # Load weight factor lfd f3, observed_value(r0) # Load observed value fnmsub f4, f1, f2, f3 # f4 = -(predicted × weight - observed) stfd f4, neg_residual(r0) # Store negative residual