[][src]Macro safe_arch::dot_product_m128d

macro_rules! dot_product_m128d {
    ($a:expr, $b:expr, $imm:expr) => { ... };
}

Performs a dot product of two m128d registers.

The output details are determined by a control mask:

  • For each lane, you can multiply that lane from $a and $b or you can take a default of 0.0
  • This forms two temporary f64 values which are summed to a single f64.
  • For each output lane, you can have the sum in that lane or 0.0.
let a = m128d::from_array([1.0, 2.0]);
let b = m128d::from_array([3.0, 4.0]);

// Bits 4 determines if we mul lanes 0, and bit 5 if we mul lanes 1.

let c = dot_product_m128d!(a, b, 0b0000_0011).to_array();
assert_eq!(c, [0.0, 0.0]); // no mul
let c = dot_product_m128d!(a, b, 0b0001_0011).to_array();
assert_eq!(c, [3.0, 3.0]); // mul lane 0 (1 * 3)
let c = dot_product_m128d!(a, b, 0b0010_0011).to_array();
assert_eq!(c, [8.0, 8.0]); // mul lane 1 (2 * 4)
let c = dot_product_m128d!(a, b, 0b0011_0011).to_array();
assert_eq!(c, [11.0, 11.0]); // mul both lanes (and summed in the next step)

// After here we have two temp lanes, which get added to form `sum`.

// Bits 0 and 1 determines if an output lane is `sum` or `0.0`.

let c = dot_product_m128d!(a, b, 0b0011_0000).to_array();
assert_eq!(c, [0.0, 0.0]); // never use sum
let c = dot_product_m128d!(a, b, 0b0011_0001).to_array();
assert_eq!(c, [11.0, 0.0]); // sum in output lane 0
let c = dot_product_m128d!(a, b, 0b0011_0010).to_array();
assert_eq!(c, [0.0, 11.0]); // sum in output lane 1
let c = dot_product_m128d!(a, b, 0b0011_0011).to_array();
assert_eq!(c, [11.0, 11.0]); // sum in both output lanes.