AVX512 has got the instruction VPTERN
(_mm512_ternarylogic_epi{32,64}
which evaluates arbitrary three-argument boolean function. A programmer
gives three input argument and an 8-bit constant which defines the function.
This CLI program lets you provide a function in textual form and obtain appropriate constant. C++ programmers may use contsexpr-based library by Samuel Neves.
Expressions may contain parentheses and operators and
/&
, or
/|
,
xor
/^
, not
/~
. There might be up to three variables, their
names are derived from the expression. By default, the first variable that
appears in an expression becomes the most significant; the order of variables
can be explicitly set with --vars
argument (see example 5).
See also a programming library that gives similar API, but works with SSE, AVX, AVX2 and x86 instruction sets.
Tautology:
$ ./ternarylogiccli.py "x & ~x" # | x | - | - | x & ~x ---+---+---+---+-------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 0 2 | 0 | 1 | 0 | 0 3 | 0 | 1 | 1 | 0 4 | 1 | 0 | 0 | 0 5 | 1 | 0 | 1 | 0 6 | 1 | 1 | 0 | 0 7 | 1 | 1 | 1 | 0 _mm512_ternarylogic_epi32(x, -, -, 0x00)
Condition expression:
$ ./ternarylogiccli.py "(cond and true_val) or (~cond and false_val)" # | cond | true_val | false_val | (cond & true_val) | (~cond & false_val) ---+------+----------+-----------+----------------------------------------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 1 2 | 0 | 1 | 0 | 0 3 | 0 | 1 | 1 | 1 4 | 1 | 0 | 0 | 0 5 | 1 | 0 | 1 | 0 6 | 1 | 1 | 0 | 1 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(cond, true_val, false_val, 0xca)
$ ./ternarylogiccli.py "a and b or c" # | a | b | c | a & b | c ---+---+---+---+----------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 1 2 | 0 | 1 | 0 | 0 3 | 0 | 1 | 1 | 1 4 | 1 | 0 | 0 | 0 5 | 1 | 0 | 1 | 1 6 | 1 | 1 | 0 | 1 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(a, b, c, 0xea)
./ternarylogiccli.py "x ^ (y & ~z)" # | x | y | z | x ^ (y & ~z) ---+---+---+---+-------------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 0 2 | 0 | 1 | 0 | 1 3 | 0 | 1 | 1 | 0 4 | 1 | 0 | 0 | 1 5 | 1 | 0 | 1 | 1 6 | 1 | 1 | 0 | 0 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(x, y, z, 0xb4)
$ ternary "a or b and c" --vars b,c,a # | b | c | a | a | b & c ---+---+---+---+----------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 1 2 | 0 | 1 | 0 | 0 3 | 0 | 1 | 1 | 1 4 | 1 | 0 | 0 | 0 5 | 1 | 0 | 1 | 1 6 | 1 | 1 | 0 | 1 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(b, c, a, 0xea) $ ternary "a or b and c" --vars c,a,b # | c | a | b | a | b & c ---+---+---+---+----------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 0 2 | 0 | 1 | 0 | 1 3 | 0 | 1 | 1 | 1 4 | 1 | 0 | 0 | 0 5 | 1 | 0 | 1 | 1 6 | 1 | 1 | 0 | 1 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(c, a, b, 0xec) $ ternary "a or b and c" --vars a,c,b # | a | c | b | a | b & c ---+---+---+---+----------- 0 | 0 | 0 | 0 | 0 1 | 0 | 0 | 1 | 0 2 | 0 | 1 | 0 | 0 3 | 0 | 1 | 1 | 1 4 | 1 | 0 | 0 | 1 5 | 1 | 0 | 1 | 1 6 | 1 | 1 | 0 | 1 7 | 1 | 1 | 1 | 1 _mm512_ternarylogic_epi32(a, c, b, 0xf8)