Skip to content

Instantly share code, notes, and snippets.

@klauspost
Created July 6, 2021 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klauspost/d4e15beb00c8a3a3307ad6e027da58d1 to your computer and use it in GitHub Desktop.
Save klauspost/d4e15beb00c8a3a3307ad6e027da58d1 to your computer and use it in GitHub Desktop.
package operand
// CalcLogTern will calculate VPTERNLOGD/VPTERNLOGD based on a function.
// Argument order is AT&T, a being *mm3, b being *mm2, c being *mm1 and destination.
// This can be used directly in VPTERNLOGD(a, b, c, CalcLogTern(...))
func CalcLogTern(fn func(a, b, c bool) bool) U8 {
var res U8
for ai, av := range []bool{false, true} {
for bi, bv := range []bool{false, true} {
for ci, cv := range []bool{false, true} {
if fn(av, bv, cv) {
res |= 1 << (uint(ai) | (uint(bi) * 2) | (uint(ci) * 4))
}
}
}
}
return res
}
package operand
import "testing"
func TestCalcLogTern(t *testing.T) {
tests := []struct {
name string
args func(a, b, c bool) bool
want U8
}{
{
name: "or",
args: func(a, b, c bool) bool {
return a || b || c
},
want: 0xfe,
},
{
name: "and",
args: func(a, b, c bool) bool {
return a && b && c
},
want: 0x80,
},
{
name: "xor",
args: func(a, b, c bool) bool {
return (a != b) != c
},
want: 0x96,
},
{
name: "onebit",
args: func(a, b, c bool) bool {
n := 0
if a {
n++
}
if b {
n++
}
if c {
n++
}
return n == 1
},
want: 0x16,
},
{
name: "twobits",
args: func(a, b, c bool) bool {
n := 0
if a {
n++
}
if b {
n++
}
if c {
n++
}
return n == 2
},
want: 0x68,
},
{
name: "bitselect",
// C ? B : A.
args: func(a, b, c bool) bool {
if c {
return b
}
return a
},
want: 0xca,
},
{
name: "carry",
// (A + B + C) > 1
args: func(a, b, c bool) bool {
n := 0
if a {
n++
}
if b {
n++
}
if c {
n++
}
return n > 1
},
want: 0xe8,
},
{
name: "add",
// (A + B + C) & 1
args: func(a, b, c bool) bool {
n := 0
if a {
n++
}
if b {
n++
}
if c {
n++
}
return n&1 == 1
},
want: 0x96,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CalcLogTern(tt.args); got != tt.want {
t.Errorf("CalcLogTern() = %b, want %b", got, tt.want)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment