mmops

Search:
Group by:

mmops - Multimedia Operators Zero-cost typed SIMD wrapper

Types

Mm[N; T] = distinct (when contains([4, 8, 16, 32], N):
  when T is float32:
    M256
  elif T is float64:
    M256d
  else:
    M256i
else:
  {.error: "Width must be 4, 8, 16, or 32".})
Width = static[int]
Number of elements in SIMD vector (4, 8, 16, or 32)

Consts

CMP_EQ_OQ = 0x00000000
CMP_LE_OS = 0x00000002
CMP_LT_OS = 0x00000001
CMP_NEQ_UQ = 0x00000004
CMP_NLE_US = 0x00000006
CMP_NLT_US = 0x00000005
CMP_ORD_Q = 0x00000007
CMP_UNORD_Q = 0x00000003
ROUND_DOWN = 0x00000001
ROUND_NEAREST = 0x00000000
ROUND_TRUNC = 0x00000003
ROUND_UP = 0x00000002

Procs

proc load[T](p: array[4, T]): Mm[4, T]
Load array into Mm vector (4 elements)
proc load[T](p: array[8, T]): Mm[8, T]
Load array into Mm vector (8 elements)
proc load[T](p: array[16, T]): Mm[16, T]
Load array into Mm vector (16 elements)
proc load[T](p: array[32, T]): Mm[32, T]
Load array into Mm vector (32 elements)

Templates

template `*`[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply packed elements in a and b
template `+`[N, T](a, b: Mm[N, T]): Mm[N, T]
Add packed elements in a and b
template `-`[N, T](a, b: Mm[N, T]): Mm[N, T]
Subtract packed elements in b from a
template `/`[N, T](a, b: Mm[N, T]): Mm[N, T]
Divide packed elements in a by b
template `<`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compare packed elements for less-than
template `<=`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compare packed elements for less-than-or-equal
template `==`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compare packed elements for equality
template `>`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compare packed elements for greater-than
template `>=`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compare packed elements for greater-than-or-equal
template `[]`[N, T](a: Mm[N, T]; index: int): T

Extract element from vector at specified index (array-style access)

Performance Note: For frequent single-element updates of float32 values, consider maintaining 8 local variables and using load() for better performance.

template `[]=`[N, T](a: var Mm[N, T]; index: int; value: T)

Set element in vector at specified index (array-style assignment)

Performance Note: For frequent single-element updates of float32 values, consider maintaining 8 local variables and using load() for better performance. Example: let vec = load([f0, f1, f2, f3, f4, f5, f6, f7])

template abs[N, T](a: Mm[N, T]): Mm[N, T]
Compute the absolute value of packed elements
template alignr[N, T](a, b: Mm[N, T]; imm8: int32): Mm[N, T]
Concatenate 16-byte blocks, shift right by imm8 bytes, return low 16 bytes
template `and`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compute the bitwise AND
template andnot[N, T](a, b: Mm[N, T]): Mm[N, T]
Compute bitwise NOT of a and then AND with b
template avg[N, T](a, b: Mm[N, T]): Mm[N, T]
Average packed unsigned elements
template bitcast[N, T, U](a: Mm[N, T]; targetType: typedesc[Mm[N, U]]): Mm[N, U]
Cast vector to different type (zero latency, compilation-only operation)
template blend[N, T](a, b: Mm[N, T]; imm8: int32): Mm[N, T]
Blend packed elements from a and b using control mask imm8
template blendv[N, T](a, b, mask: Mm[N, T]): Mm[N, T]
Blend packed elements from a and b using mask
template ceil[N, T](a: Mm[N, T]): Mm[N, T]
Round packed elements up to integer
template convert[N, T](a: Mm[N, T]): auto
Convert between integer and floating-point types
template extract[N, T](a: Mm[N, T]; index: int32): T
Extract element from vector at specified index
template fastSqrt[N, T](a: Mm[N, T]): Mm[N, T]
Compute the approximate reciprocal square root
template floor[N, T](a: Mm[N, T]): Mm[N, T]
Round packed elements down to integer
template fma[N, T](a, b, c: Mm[N, T]): Mm[N, T]
Fused multiply-add (a * b + c)
template gather[T](p: openArray[T]; vindex: Mm[4, int64]; scale: int32): Mm[4, T]
Gather elements from memory using 64-bit indices
template gather[T](p: openArray[T]; vindex: Mm[8, int32]; scale: int32): Mm[8, T]
Gather elements from memory using 32-bit indices
template hadd[N, T](a, b: Mm[N, T]): Mm[N, T]
Horizontally add adjacent pairs of elements, packing results
template hsub[N, T](a, b: Mm[N, T]): Mm[N, T]
Horizontally subtract adjacent pairs of elements, packing results
template initMm(e3, e2, e1, e0: float64): Mm[4, float64]
template initMm(e3, e2, e1, e0: int64): Mm[4, int64]
template initMm(e3, e2, e1, e0: uint64): Mm[4, uint64]
template initMm(e7, e6, e5, e4, e3, e2, e1, e0: float32): Mm[8, float32]
template initMm(e7, e6, e5, e4, e3, e2, e1, e0: int32): Mm[8, int32]
template initMm(e7, e6, e5, e4, e3, e2, e1, e0: uint32): Mm[8, uint32]
template initMm(e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2,
                e1, e0: int16): Mm[16, int16]
template initMm(e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2,
                e1, e0: uint16): Mm[16, uint16]
template initMm(e31, e30, e29, e28, e27, e26, e25, e24, e23, e22, e21, e20, e19,
                e18, e17, e16, e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5,
                e4, e3, e2, e1, e0: int8): Mm[32, int8]
template initMm(e31, e30, e29, e28, e27, e26, e25, e24, e23, e22, e21, e20, e19,
                e18, e17, e16, e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5,
                e4, e3, e2, e1, e0: uint8): Mm[32, uint8]
template initMm[N, T](t: typedesc[Mm[N, T]]): Mm[N, T]
template madd[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply packed 16-bit integers, horizontally add adjacent 32-bit results
template mask[N, T](a: Mm[N, T]): int32
Create mask from the most significant bit of each element
template maskLoad[N, T](p: openArray[T]; mask: Mm[N, T]): Mm[N, T]
Conditionally load elements from memory using mask
template maskStore[N, T](p: var openArray[T]; mask: Mm[N, T]; a: Mm[N, T])
Conditionally store elements to memory using mask
template max[N, T](a, b: Mm[N, T]): Mm[N, T]
Return packed maximum values
template min[N, T](a, b: Mm[N, T]): Mm[N, T]
Return packed minimum values
template mul32[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply low 32-bit integers from each 64-bit element, returning 64-bit results
template mulHi[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply packed elements, returning high bits of intermediate results
template mulHrs[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply packed signed 16-bit integers, truncate to 18 MSBs, round by adding 1
template mulLo[N, T](a, b: Mm[N, T]): Mm[N, T]
Multiply packed elements, returning low bits of intermediate results
template `not`[N, T](a: Mm[N, T]): Mm[N, T]
Compute the bitwise NOT
template `or`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compute the bitwise OR
template pack[N, T](a, b: Mm[N, T]): Mm[N, T]
Convert packed elements to smaller type using signed saturation
template packus[N, T](a, b: Mm[N, T]): Mm[N, T]
Convert packed elements to smaller unsigned type using unsigned saturation
template permute[N, T](a: Mm[N, T]; imm8: int32): Mm[N, T]
Shuffle elements using the control in imm8
template permuteVar[N, T](a: Mm[N, T]; idx: Mm[N, int32]): Mm[N, T]
Shuffle elements using control indices in idx
template round[N, T](a: Mm[N, T]): Mm[N, T]
Round packed elements to nearest integer
template sad[N, T](a, b: Mm[N, T]): Mm[N, T]
Compute absolute differences, horizontally sum each consecutive 8 differences
template saturatedAdd[N, T](a, b: Mm[N, T]): Mm[N, T]
Add packed elements using saturation
template saturatedSub[N, T](a, b: Mm[N, T]): Mm[N, T]
Subtract packed elements using saturation
template set(e3, e2, e1, e0: float64): Mm[4, float64]
Set 4 double-precision floating-point elements with specified values (e3 is highest)
template set(e3, e2, e1, e0: int64): Mm[4, int64]
Set 4 64-bit integer elements with specified values (e3 is highest)
template set(e3, e2, e1, e0: uint64): Mm[4, uint64]
Set 4 64-bit unsigned integer elements with specified values (e3 is highest)
template set(e7, e6, e5, e4, e3, e2, e1, e0: float32): Mm[8, float32]
Set 8 single-precision floating-point elements with specified values (e7 is highest)
template set(e7, e6, e5, e4, e3, e2, e1, e0: int32): Mm[8, int32]
Set 8 32-bit integer elements with specified values (e7 is highest)
template set(e7, e6, e5, e4, e3, e2, e1, e0: uint32): Mm[8, uint32]
Set 8 32-bit unsigned integer elements with specified values (e7 is highest)
template set(e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2, e1,
             e0: int16): Mm[16, int16]
Set 16 16-bit integer elements with specified values (e15 is highest)
template set(e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2, e1,
             e0: uint16): Mm[16, uint16]
Set 16 16-bit unsigned integer elements with specified values (e15 is highest)
template set(e31, e30, e29, e28, e27, e26, e25, e24, e23, e22, e21, e20, e19,
             e18, e17, e16, e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5,
             e4, e3, e2, e1, e0: int8): Mm[32, int8]
Set 32 8-bit integer elements with specified values (e31 is highest)
template set(e31, e30, e29, e28, e27, e26, e25, e24, e23, e22, e21, e20, e19,
             e18, e17, e16, e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5,
             e4, e3, e2, e1, e0: uint8): Mm[32, uint8]
Set 32 8-bit unsigned integer elements with specified values (e31 is highest)
template `shl`[N, T](a: Mm[N, T]; imm: int32): Mm[N, T]
Shift packed elements left by imm bits
template `shr`[N, T](a: Mm[N, T]; imm: int32): Mm[N, T]
Shift packed elements right by imm bits
template shuffle[N, T](a: Mm[N, T]; imm8: int32): Mm[N, T]
Shuffle elements using control in imm8
template sign[N, T](a, b: Mm[N, T]): Mm[N, T]
Negate elements in a when corresponding element in b is negative
template splat[N](val: float32): Mm[N, float32]
Broadcast a single-precision floating-point value to all elements
template splat[N](val: float64): Mm[N, float64]
Broadcast a double-precision floating-point value to all elements
template splat[N](val: int8): Mm[N, int8]
Broadcast an 8-bit integer value to all elements
template splat[N](val: int16): Mm[N, int16]
Broadcast a 16-bit integer value to all elements
template splat[N](val: int32): Mm[N, int32]
Broadcast a 32-bit integer value to all elements
template splat[N](val: int64): Mm[N, int64]
Broadcast a 64-bit integer value to all elements
template splat[N](val: uint8): Mm[N, uint8]
Broadcast an 8-bit unsigned integer value to all elements
template splat[N](val: uint16): Mm[N, uint16]
Broadcast a 16-bit unsigned integer value to all elements
template splat[N](val: uint32): Mm[N, uint32]
Broadcast a 32-bit unsigned integer value to all elements
template splat[N](val: uint64): Mm[N, uint64]
Broadcast a 64-bit unsigned integer value to all elements
template sqrt[N, T](a: Mm[N, T]): Mm[N, T]
Compute the square root of packed elements
template store[T](m: Mm[4, T]): array[4, T]
Store Mm vector to array (4 elements)
template store[T](m: Mm[8, T]): array[8, T]
Store Mm vector to array (8 elements)
template store[T](m: Mm[16, T]): array[16, T]
Store Mm vector to array (16 elements)
template store[T](m: Mm[32, T]): array[32, T]
Store Mm vector to array (32 elements)
template streamLoad[T](p: array[8, T]): Mm[8, T]
Load data from memory using non-temporal memory hint
template sum[N, T](a: Mm[N, T]): T
Sum all elements, returning scalar result
template toArray[T](m: Mm[4, T]): array[4, T]
template toArray[T](m: Mm[8, T]): array[8, T]
template toArray[T](m: Mm[16, T]): array[16, T]
template toArray[T](m: Mm[32, T]): array[32, T]
template toMm[T](p: array[4, T]): Mm[4, T]
template toMm[T](p: array[8, T]): Mm[8, T]
template toMm[T](p: array[16, T]): Mm[16, T]
template toMm[T](p: array[32, T]): Mm[32, T]
template unpackHi[N, T](a, b: Mm[N, T]): Mm[N, T]
Unpack and interleave elements from the high half
template unpackLo[N, T](a, b: Mm[N, T]): Mm[N, T]
Unpack and interleave elements from the low half
template vshl[N, T](a, count: Mm[N, T]): Mm[N, T]
Shift packed elements left by amounts specified in count
template vshr[N, T](a, count: Mm[N, T]): Mm[N, T]
Shift packed elements right by amounts specified in count
template `xor`[N, T](a, b: Mm[N, T]): Mm[N, T]
Compute the bitwise XOR
template zero[N, T](t: typedesc[Mm[N, T]]): Mm[N, T]
Return vector with all elements set to zero