Files
avo/internal/inst/table.go

136 lines
3.0 KiB
Go
Raw Permalink Normal View History

2018-11-24 14:55:51 -08:00
package inst
all: AVX-512 (#217) Extends avo to support most AVX-512 instruction sets. The instruction type is extended to support suffixes. The K family of opmask registers is added to the register package, and the operand package is updated to support the new operand types. Move instruction deduction in `Load` and `Store` is extended to support KMOV* and VMOV* forms. Internal code generation packages were overhauled. Instruction database loading required various messy changes to account for the additional complexities of the AVX-512 instruction sets. The internal/api package was added to introduce a separation between instruction forms in the database, and the functions avo provides to create them. This was required since with instruction suffixes there is no longer a one-to-one mapping between instruction constructors and opcodes. AVX-512 bloated generated source code size substantially, initially increasing compilation and CI test times to an unacceptable level. Two changes were made to address this: 1. Instruction constructors in the `x86` package moved to an optab-based approach. This compiles substantially faster than the verbose code generation we had before. 2. The most verbose code-generated tests are moved under build tags and limited to a stress test mode. Stress test builds are run on schedule but not in regular CI. An example of AVX-512 accelerated 16-lane MD5 is provided to demonstrate and test the new functionality. Updates #20 #163 #229 Co-authored-by: Vaughn Iverson <vsivsi@yahoo.com>
2021-11-12 18:35:36 -08:00
import (
"sort"
"strings"
)
2018-11-25 17:11:24 -08:00
//go:generate avogen -bootstrap -data ../data -output ztable.go godata
2018-11-24 14:55:51 -08:00
// Lookup returns the instruction with the given opcode. Boolean return value
// indicates whether the instruction was found.
2018-11-24 14:55:51 -08:00
func Lookup(opcode string) (Instruction, bool) {
for _, i := range Instructions {
if i.Opcode == opcode {
return i, true
}
}
return Instruction{}, false
}
all: AVX-512 (#217) Extends avo to support most AVX-512 instruction sets. The instruction type is extended to support suffixes. The K family of opmask registers is added to the register package, and the operand package is updated to support the new operand types. Move instruction deduction in `Load` and `Store` is extended to support KMOV* and VMOV* forms. Internal code generation packages were overhauled. Instruction database loading required various messy changes to account for the additional complexities of the AVX-512 instruction sets. The internal/api package was added to introduce a separation between instruction forms in the database, and the functions avo provides to create them. This was required since with instruction suffixes there is no longer a one-to-one mapping between instruction constructors and opcodes. AVX-512 bloated generated source code size substantially, initially increasing compilation and CI test times to an unacceptable level. Two changes were made to address this: 1. Instruction constructors in the `x86` package moved to an optab-based approach. This compiles substantially faster than the verbose code generation we had before. 2. The most verbose code-generated tests are moved under build tags and limited to a stress test mode. Stress test builds are run on schedule but not in regular CI. An example of AVX-512 accelerated 16-lane MD5 is provided to demonstrate and test the new functionality. Updates #20 #163 #229 Co-authored-by: Vaughn Iverson <vsivsi@yahoo.com>
2021-11-12 18:35:36 -08:00
// OperandTypes returns all the operand types that appear in the provided
// instructions.
func OperandTypes(is []Instruction) []string {
set := map[string]bool{}
for _, i := range is {
for _, f := range i.Forms {
for _, op := range f.Operands {
set[op.Type] = true
}
}
}
return sortedslice(set)
}
// ImplicitRegisters returns all the registers that appear as implicit operands
// in the provided instructions.
func ImplicitRegisters(is []Instruction) []string {
set := map[string]bool{}
for _, i := range is {
for _, f := range i.Forms {
for _, op := range f.ImplicitOperands {
set[op.Register] = true
}
}
}
return sortedslice(set)
}
// UniqueSuffixes returns all the non-empty suffixes that appear in the provided
// instructions.
func UniqueSuffixes(is []Instruction) []Suffix {
// Collect set.
set := map[Suffix]bool{}
for _, i := range is {
for _, f := range i.Forms {
for _, suffixes := range f.SupportedSuffixes() {
for _, suffix := range suffixes {
set[suffix] = true
}
}
}
}
// Convert to sorted slice.
suffixes := make([]Suffix, 0, len(set))
for suffix := range set {
suffixes = append(suffixes, suffix)
}
sort.Slice(suffixes, func(i, j int) bool {
return suffixes[i] < suffixes[j]
})
return suffixes
}
// SuffixesClasses returns all possible classes of suffix combinations.
func SuffixesClasses(is []Instruction) map[string][]Suffixes {
classes := map[string][]Suffixes{}
for _, i := range is {
for _, f := range i.Forms {
class := f.SuffixesClass()
if _, ok := classes[class]; ok {
continue
}
classes[class] = f.SupportedSuffixes()
}
}
return classes
}
// ISAs returns all the unique ISAs seen in the given instructions.
func ISAs(is []Instruction) []string {
set := map[string]bool{}
for _, i := range is {
for _, f := range i.Forms {
for _, isa := range f.ISA {
set[isa] = true
}
}
}
return sortedslice(set)
}
// ISACombinations returns all the unique combinations of ISAs seen in the given
// instructions.
func ISACombinations(is []Instruction) [][]string {
var combinations [][]string
seen := map[string]bool{}
for _, i := range is {
for _, f := range i.Forms {
isas := append([]string(nil), f.ISA...)
sort.Strings(isas)
key := strings.Join(isas, ",")
if !seen[key] {
combinations = append(combinations, isas)
seen[key] = true
}
}
}
return combinations
}
// sortedslice builds a sorted slice of strings from a set.
func sortedslice(set map[string]bool) []string {
ss := make([]string, 0, len(set))
for s := range set {
ss = append(ss, s)
}
sort.Strings(ss)
return ss
}