fmsub
Floating Multiply-Subtract - FC 00 00 38
fmsub

Instruction Syntax

Mnemonic Format Flags
fmsub frD,frA,frC,frB Rc = 0
fmsub. frD,frA,frC,frB Rc = 1

Instruction Encoding

1
1
1
1
1
1
D
D
D
D
D
A
A
A
A
A
B
B
B
B
B
C
C
C
C
C
0
1
1
1
0
0
Rc

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 11100 (28)
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 placed into floating-point register frD.

Note: This is a fused multiply-subtract operation. The intermediate product (frA × frC) is computed to infinite precision and is not rounded before subtracting frB. Only one rounding operation occurs, at the end, which provides higher accuracy than separate multiply and subtract operations. This instruction is essential for high-performance computing and numerical algorithms.

Affected Registers

Condition Register (CR1 field)

(if Rc = 1)

Floating-Point Status and Control Register (FPSCR)

Affected fields:

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 Multiply-Subtract Operation

lfd f1, multiplicand(r0)   # Load multiplicand (A)
lfd f2, subtrahend(r0)     # Load subtrahend (B)
lfd f3, multiplier(r0)     # Load multiplier (C)
fmsub f4, f1, f3, f2       # f4 = (f1 × f3) - f2
stfd f4, result(r0)        # Store result

Digital Signal Processing: Biquad Filter

# Biquad filter coefficient application with subtraction
# y[n] = b₀×x[n] + state - a₁×y[n-1]
lfd f1, b0_coeff(r0)       # Load b₀ coefficient
lfd f2, input_sample(r0)   # Load input x[n]
lfd f3, filter_state(r0)   # Load filter state
lfd f4, a1_coeff(r0)       # Load a₁ coefficient
lfd f5, prev_output(r0)    # Load y[n-1]
fmsub f6, f1, f2, f0       # f6 = b₀ × x[n] - 0 = b₀ × x[n]
fadd f6, f6, f3            # f6 = b₀×x[n] + state
fmsub f7, f4, f5, f6       # f7 = f6 - a₁×y[n-1]
stfd f7, output_sample(r0) # Store y[n]

3D Graphics: Distance Calculation

# Calculate squared distance with optimization: d² = (x₁-x₂)² + (y₁-y₂)² + (z₁-z₂)²
# Using fmsub for: d² = x₁² - 2×x₁×x₂ + x₂² (part of distance formula)
lfd f1, point1_x(r0)       # Load x₁
lfd f2, point1_y(r0)       # Load y₁
lfd f3, point1_z(r0)       # Load z₁
lfd f4, point2_x(r0)       # Load x₂
lfd f5, point2_y(r0)       # Load y₂
lfd f6, point2_z(r0)       # Load z₂
lfd f7, two_constant(r0)   # Load 2.0
fmul f8, f1, f1            # f8 = x₁²
fmul f9, f4, f4            # f9 = x₂²
fmsub f10, f7, f1, f8      # f10 = f8 - 2×x₁ (partial calculation)
# Continue with complete distance calculation...

Physics: Force Calculation

# Calculate net force: F_net = ma - friction
# F_net = mass × acceleration - friction_coefficient × normal_force
lfd f1, mass(r0)           # Load mass
lfd f2, acceleration(r0)   # Load acceleration
lfd f3, friction_coeff(r0) # Load friction coefficient
lfd f4, normal_force(r0)   # Load normal force
fmsub f5, f1, f2, f0       # f5 = mass × acceleration - 0
fmsub f6, f3, f4, f5       # f6 = f5 - friction_coeff × normal_force
stfd f6, net_force(r0)     # Store net force

Financial Calculation: Loan Payment

# Calculate remaining balance: new_balance = old_balance × (1 + rate) - payment
lfd f1, old_balance(r0)    # Load current balance
lfd f2, interest_rate(r0)  # Load interest rate
lfd f3, payment(r0)        # Load payment amount
lfd f4, one_constant(r0)   # Load 1.0
fadd f5, f4, f2            # f5 = 1 + rate
fmsub f6, f1, f5, f3       # f6 = old_balance × (1 + rate) - payment
stfd f6, new_balance(r0)   # Store new balance

Game Physics: Projectile Motion

# Calculate projectile position: y = v₀t - ½gt²
# Rearranged as: y = v₀ × t - (½g) × t²
lfd f1, initial_velocity(r0) # Load initial velocity
lfd f2, time(r0)           # Load time
lfd f3, gravity_half(r0)   # Load ½g (half gravity)
lfd f4, time_squared(r0)   # Load t² (precomputed)
fmsub f5, f1, f2, f0       # f5 = v₀ × t - 0
fmsub f6, f3, f4, f5       # f6 = f5 - (½g) × t² = v₀t - ½gt²
stfd f6, position_y(r0)    # Store Y position

Audio Processing: Echo/Delay Effect

# Echo effect: output = input × gain - delayed_signal × feedback
lfd f1, input_signal(r0)   # Load input signal
lfd f2, gain_factor(r0)    # Load gain factor
lfd f3, delayed_signal(r0) # Load delayed signal
lfd f4, feedback_coeff(r0) # Load feedback coefficient
fmsub f5, f1, f2, f0       # f5 = input × gain - 0
fmsub f6, f3, f4, f5       # f6 = f5 - delayed × feedback
stfd f6, output_signal(r0) # Store output signal

Machine Learning: Gradient Descent

# Weight update: new_weight = old_weight - learning_rate × gradient
# Using fmsub: new_weight = old_weight × 1 - learning_rate × gradient  
lfd f1, old_weight(r0)     # Load current weight
lfd f2, learning_rate(r0)  # Load learning rate
lfd f3, gradient(r0)       # Load gradient
lfd f4, one_constant(r0)   # Load 1.0
fmsub f5, f1, f4, f0       # f5 = old_weight × 1 - 0 = old_weight
fmsub f6, f2, f3, f5       # f6 = f5 - learning_rate × gradient
stfd f6, new_weight(r0)    # Store updated weight

Scientific Computing: Error Calculation

# Calculate relative error: error = computed_value × scale - reference_value
lfd f1, computed_value(r0) # Load computed result
lfd f2, scale_factor(r0)   # Load scaling factor
lfd f3, reference_value(r0) # Load reference value
fmsub f4, f1, f2, f3       # f4 = computed × scale - reference
stfd f4, error_value(r0)   # Store error

Graphics: Color Blending

# Alpha blending: result = src_color × alpha - dst_color × (1-alpha)
# Simplified version using fmsub for one component
lfd f1, src_color(r0)      # Load source color
lfd f2, alpha(r0)          # Load alpha value
lfd f3, dst_color(r0)      # Load destination color
lfd f4, one_minus_alpha(r0) # Load (1-alpha)
fmsub f5, f1, f2, f0       # f5 = src × alpha - 0
fmsub f6, f3, f4, f5       # f6 = f5 - dst × (1-alpha) (for subtract blend mode)
stfd f6, blended_color(r0) # Store blended color

Numerical Analysis: Finite Difference

# Calculate finite difference: df/dx ≈ (f(x+h) - f(x)) / h
# Rearranged: df/dx = f(x+h) × (1/h) - f(x) × (1/h)
lfd f1, f_x_plus_h(r0)     # Load f(x+h)
lfd f2, f_x(r0)            # Load f(x)
lfd f3, inv_h(r0)          # Load 1/h
fmsub f4, f1, f3, f0       # f4 = f(x+h) × (1/h) - 0
fmsub f5, f2, f3, f4       # f5 = f4 - f(x) × (1/h) = derivative approximation
stfd f5, derivative(r0)    # Store derivative

Related Instructions

fmadd, fmadds, fmsubs, fnmadd, fnmsub, fmul, fsub

Back to Index