Instruction Syntax
Mnemonic | Format | Flags |
fnmadd | frD,frA,frC,frB | Rc = 0 |
fnmadd. | 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 (addend) |
frC | 21-25 | Source floating-point register C (multiplier) |
XO | 26-30 | 11111 (31) |
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 added to this intermediate product. The result is then negated and placed into floating-point register frD.
Note: This is a fused negative multiply-add operation. The intermediate product (frA × frC) is computed to infinite precision, added to frB, 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 useful for certain mathematical algorithms and signal processing applications.
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-Add Operation
lfd f1, multiplicand(r0) # Load multiplicand (A) lfd f2, addend(r0) # Load addend (B) lfd f3, multiplier(r0) # Load multiplier (C) fnmadd f4, f1, f3, f2 # f4 = -((f1 × f3) + f2) stfd f4, result(r0) # Store result
Signal Processing: Inverted Filter Response
# Implement inverted filter: output = -(coeff × input + bias) lfd f1, filter_coeff(r0) # Load filter coefficient lfd f2, input_signal(r0) # Load input signal lfd f3, bias_value(r0) # Load bias value fnmadd f4, f1, f2, f3 # f4 = -(coeff × input + bias) stfd f4, inverted_output(r0) # Store inverted result
Physics: Damped Oscillation
# Calculate damping force: F_damping = -(k×x + c×v) # Where k is spring constant, x is displacement, c is damping coefficient, 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 c lfd f4, velocity(r0) # Load velocity v fnmadd f5, f1, f2, f0 # f5 = -(k × x + 0) = -kx fnmadd f6, f3, f4, f5 # f6 = -(c × v) + f5 = -(kx + cv) stfd f6, damping_force(r0) # Store damping force
Graphics: Inverse Transform
# Calculate inverse transformation: result = -(scale × value + offset) lfd f1, scale_factor(r0) # Load scale factor lfd f2, input_value(r0) # Load input value lfd f3, offset_value(r0) # Load offset fnmadd f4, f1, f2, f3 # f4 = -(scale × value + offset) stfd f4, inverse_result(r0) # Store inverse result
Audio Processing: Phase Inversion
# Create phase-inverted signal: output = -(gain × input + dc_bias) lfd f1, gain_factor(r0) # Load gain factor lfd f2, audio_input(r0) # Load audio input lfd f3, dc_bias(r0) # Load DC bias fnmadd f4, f1, f2, f3 # f4 = -(gain × input + dc_bias) stfd f4, inverted_audio(r0) # Store phase-inverted audio
Mathematical: Negative Quadratic Form
# Calculate -(ax² + b): negative quadratic evaluation lfd f1, coeff_a(r0) # Load coefficient a lfd f2, x_value(r0) # Load x lfd f3, coeff_b(r0) # Load coefficient b fnmadd f4, f1, f2, f3 # f4 = -(a × x + b) (partial quadratic) # For full quadratic -(ax² + bx + c), this would be part of Horner's method stfd f4, neg_quadratic(r0) # Store negative result
Control Systems: Negative Feedback
# Implement negative feedback: error = -(Kp × input + setpoint) lfd f1, proportional_gain(r0) # Load Kp gain lfd f2, system_input(r0) # Load input lfd f3, setpoint(r0) # Load setpoint fnmadd f4, f1, f2, f3 # f4 = -(Kp × input + setpoint) stfd f4, feedback_error(r0) # Store feedback error
Game Physics: Reverse Force Calculation
# Calculate opposing force: F_oppose = -(mass × acceleration + friction) lfd f1, object_mass(r0) # Load mass lfd f2, acceleration(r0) # Load acceleration lfd f3, friction_force(r0) # Load friction force fnmadd f4, f1, f2, f3 # f4 = -(mass × acceleration + friction) stfd f4, opposing_force(r0) # Store opposing force
Financial Modeling: Negative Cash Flow
# Calculate negative cash flow: outflow = -(rate × principal + fees) lfd f1, interest_rate(r0) # Load interest rate lfd f2, principal(r0) # Load principal amount lfd f3, fees(r0) # Load fees fnmadd f4, f1, f2, f3 # f4 = -(rate × principal + fees) stfd f4, cash_outflow(r0) # Store negative cash flow
Scientific Computing: Negative Gradient
# Calculate negative gradient component: -∇f = -(∂f/∂x × Δx + bias) lfd f1, partial_deriv(r0) # Load ∂f/∂x lfd f2, delta_x(r0) # Load Δx lfd f3, gradient_bias(r0) # Load bias term fnmadd f4, f1, f2, f3 # f4 = -(∂f/∂x × Δx + bias) stfd f4, neg_gradient(r0) # Store negative gradient component