Instruction Syntax
Mnemonic | Format | Flags |
fmadds | frD,frA,frC,frB | Rc = 0 |
fmadds. | 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 (addend) |
frC | 21-25 | Source floating-point register C (multiplier) |
XO | 26-30 | 11101 (29) |
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 added to this intermediate product. The result is rounded to single-precision and placed into floating-point register frD.
Note: This is a fused multiply-add operation optimized for single-precision. The intermediate product (frA × frC) is computed to infinite precision, added to frB, and then rounded to single-precision format. This provides both the accuracy benefits of fused multiply-add 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 Multiply-Add
lfs f1, multiplicand(r0) # Load single-precision multiplicand lfs f2, addend(r0) # Load single-precision addend lfs f3, multiplier(r0) # Load single-precision multiplier fmadds f4, f1, f3, f2 # f4 = SINGLE((f1 × f3) + f2) stfs f4, result(r0) # Store single-precision result
3D Graphics: Vertex Transformation (Single-Precision)
# Single-precision 3D vertex transformation: x' = m11×x + m12×y + m13×z + tx lfs f1, matrix_11(r0) # Load m11 (single-precision) lfs f2, matrix_12(r0) # Load m12 lfs f3, matrix_13(r0) # Load m13 lfs f4, vertex_x(r0) # Load vertex X lfs f5, vertex_y(r0) # Load vertex Y lfs f6, vertex_z(r0) # Load vertex Z lfs f7, translation_x(r0) # Load translation TX fmuls f8, f1, f4 # f8 = m11 × x fmadds f8, f2, f5, f8 # f8 = (m12 × y) + f8 fmadds f8, f3, f6, f8 # f8 = (m13 × z) + f8 fadds f8, f8, f7 # f8 = f8 + tx (final transformed X) stfs f8, transformed_x(r0) # Store transformed X coordinate
Audio Processing: Single-Precision FIR Filter
# Single-precision FIR filter tap accumulation lfs f1, filter_coeff_0(r0) # Load coefficient 0 lfs f2, filter_coeff_1(r0) # Load coefficient 1 lfs f3, filter_coeff_2(r0) # Load coefficient 2 lfs f4, sample_0(r0) # Load sample 0 lfs f5, sample_1(r0) # Load sample 1 lfs f6, sample_2(r0) # Load sample 2 fmuls f7, f1, f4 # f7 = coeff0 × sample0 fmadds f7, f2, f5, f7 # f7 = (coeff1 × sample1) + f7 fmadds f7, f3, f6, f7 # f7 = (coeff2 × sample2) + f7 stfs f7, filter_output(r0) # Store filtered output
Game Physics: Single-Precision Force Calculation
# Calculate total force: F = F_gravity + F_wind + F_friction # Where F_wind = wind_coeff × velocity × air_density lfs f1, gravity_force(r0) # Load gravity force lfs f2, wind_coeff(r0) # Load wind coefficient lfs f3, velocity(r0) # Load velocity lfs f4, air_density(r0) # Load air density lfs f5, friction_force(r0) # Load friction force fmadds f6, f2, f3, f1 # f6 = (wind_coeff × velocity) + gravity fmadds f7, f6, f4, f5 # f7 = (f6 × air_density) + friction (total force) stfs f7, total_force(r0) # Store total force
Computer Graphics: Single-Precision Color Blending
# Alpha blending: result = src × alpha + dst × (1-alpha) lfs f1, src_red(r0) # Load source red component lfs f2, alpha_value(r0) # Load alpha value lfs f3, dst_red(r0) # Load destination red component lfs f4, one_minus_alpha(r0) # Load (1-alpha) fmadds f5, f1, f2, f0 # f5 = src × alpha + 0 fmadds f6, f3, f4, f5 # f6 = dst × (1-alpha) + f5 (blended red) stfs f6, blended_red(r0) # Store blended red component
Machine Learning: Single-Precision Neural Network
# Neural network layer (single-precision): output = w1×x1 + w2×x2 + w3×x3 + bias lfs f1, weight_1(r0) # Load weight 1 lfs f2, weight_2(r0) # Load weight 2 lfs f3, weight_3(r0) # Load weight 3 lfs f4, input_1(r0) # Load input 1 lfs f5, input_2(r0) # Load input 2 lfs f6, input_3(r0) # Load input 3 lfs f7, bias_value(r0) # Load bias fmadds f8, f1, f4, f7 # f8 = (w1 × x1) + bias fmadds f8, f2, f5, f8 # f8 = (w2 × x2) + f8 fmadds f8, f3, f6, f8 # f8 = (w3 × x3) + f8 (neuron output) stfs f8, neuron_output(r0) # Store neuron output
Scientific Computing: Single-Precision Polynomial
# Evaluate polynomial: f(x) = ax² + bx + c (single-precision) lfs f1, coeff_a(r0) # Load coefficient a lfs f2, coeff_b(r0) # Load coefficient b lfs f3, coeff_c(r0) # Load coefficient c lfs f4, x_value(r0) # Load x fmadds f5, f1, f4, f2 # f5 = ax + b fmadds f6, f5, f4, f3 # f6 = (ax + b)x + c = ax² + bx + c stfs f6, polynomial_result(r0) # Store polynomial result
Real-Time Audio: Single-Precision Reverb
# Simple reverb: output = dry × dry_gain + wet × wet_gain + feedback lfs f1, dry_signal(r0) # Load dry signal lfs f2, dry_gain(r0) # Load dry gain lfs f3, wet_signal(r0) # Load wet signal lfs f4, wet_gain(r0) # Load wet gain lfs f5, feedback_signal(r0) # Load feedback signal fmadds f6, f1, f2, f0 # f6 = dry × dry_gain + 0 fmadds f6, f3, f4, f6 # f6 = (wet × wet_gain) + f6 fadds f6, f6, f5 # f6 = f6 + feedback (reverb output) stfs f6, reverb_output(r0) # Store reverb output
Game AI: Single-Precision Steering Behavior
# Steering force: F = seek_force × seek_weight + avoid_force × avoid_weight + wander_bias lfs f1, seek_force_x(r0) # Load seek force X component lfs f2, seek_weight(r0) # Load seek weight lfs f3, avoid_force_x(r0) # Load avoidance force X lfs f4, avoid_weight(r0) # Load avoidance weight lfs f5, wander_bias_x(r0) # Load wander bias X fmadds f6, f1, f2, f5 # f6 = (seek_force × seek_weight) + wander_bias fmadds f7, f3, f4, f6 # f7 = (avoid_force × avoid_weight) + f6 stfs f7, steering_force_x(r0) # Store final steering force X
Financial Computing: Single-Precision Interest
# Compound interest calculation: amount = principal × (1 + rate) + deposit lfs f1, principal(r0) # Load principal amount lfs f2, interest_rate(r0) # Load interest rate lfs f3, one_constant(r0) # Load 1.0 lfs f4, monthly_deposit(r0) # Load monthly deposit fadds f5, f3, f2 # f5 = 1 + rate fmadds f6, f1, f5, f4 # f6 = principal × (1 + rate) + deposit stfs f6, new_amount(r0) # Store new amount