diff options
Diffstat (limited to 'vendor/github.com/mmcloughlin')
35 files changed, 38443 insertions, 0 deletions
diff --git a/vendor/github.com/mmcloughlin/avo/LICENSE b/vendor/github.com/mmcloughlin/avo/LICENSE new file mode 100644 index 0000000..c986d80 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Michael McLoughlin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/mmcloughlin/avo/attr/attr.go b/vendor/github.com/mmcloughlin/avo/attr/attr.go new file mode 100644 index 0000000..016e0a4 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/attr/attr.go @@ -0,0 +1,102 @@ +// Package attr provides attributes for text and data sections. +package attr + +import ( + "fmt" + "math/bits" + "strings" +) + +// Attribute represents TEXT or DATA flags. +type Attribute uint16 + +// Reference: https://github.com/golang/go/blob/aafe257390cc9048e8b5df898fabd79a9e0d4c39/src/runtime/textflag.h#L11-L37 +// +// // Don't profile the marked routine. This flag is deprecated. +// #define NOPROF 1 +// // It is ok for the linker to get multiple of these symbols. It will +// // pick one of the duplicates to use. +// #define DUPOK 2 +// // Don't insert stack check preamble. +// #define NOSPLIT 4 +// // Put this data in a read-only section. +// #define RODATA 8 +// // This data contains no pointers. +// #define NOPTR 16 +// // This is a wrapper function and should not count as disabling 'recover'. +// #define WRAPPER 32 +// // This function uses its incoming context register. +// #define NEEDCTXT 64 +// // Allocate a word of thread local storage and store the offset from the +// // thread local base to the thread local storage in this variable. +// #define TLSBSS 256 +// // Do not insert instructions to allocate a stack frame for this function. +// // Only valid on functions that declare a frame size of 0. +// // TODO(mwhudson): only implemented for ppc64x at present. +// #define NOFRAME 512 +// // Function can call reflect.Type.Method or reflect.Type.MethodByName. +// #define REFLECTMETHOD 1024 +// // Function is the top of the call stack. Call stack unwinders should stop +// // at this function. +// #define TOPFRAME 2048 +// +const ( + NOPROF Attribute = 1 << iota + DUPOK + NOSPLIT + RODATA + NOPTR + WRAPPER + NEEDCTXT + _ + TLSBSS + NOFRAME + REFLECTMETHOD + TOPFRAME +) + +// Asm returns a representation of the attributes in assembly syntax. This may use macros from "textflags.h"; see ContainsTextFlags() to determine if this header is required. +func (a Attribute) Asm() string { + parts, rest := a.split() + if len(parts) == 0 || rest != 0 { + parts = append(parts, fmt.Sprintf("%d", rest)) + } + return strings.Join(parts, "|") +} + +// ContainsTextFlags returns whether the Asm() representation requires macros in "textflags.h". +func (a Attribute) ContainsTextFlags() bool { + flags, _ := a.split() + return len(flags) > 0 +} + +// split splits a into known flags and any remaining bits. +func (a Attribute) split() ([]string, Attribute) { + var flags []string + var rest Attribute + for a != 0 { + i := uint(bits.TrailingZeros16(uint16(a))) + bit := Attribute(1) << i + if flag := attrname[bit]; flag != "" { + flags = append(flags, flag) + } else { + rest |= bit + } + a ^= bit + } + return flags, rest +} + +var attrname = map[Attribute]string{ + NOPROF: "NOPROF", + DUPOK: "DUPOK", + NOSPLIT: "NOSPLIT", + RODATA: "RODATA", + NOPTR: "NOPTR", + WRAPPER: "WRAPPER", + NEEDCTXT: "NEEDCTXT", + TLSBSS: "TLSBSS", + NOFRAME: "NOFRAME", + REFLECTMETHOD: "REFLECTMETHOD", + TOPFRAME: "TOPFRAME", +} diff --git a/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go b/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go new file mode 100644 index 0000000..8fd61e1 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go @@ -0,0 +1,312 @@ +// Package buildtags provides types for representing and manipulating build constraints. +// +// In Go, build constraints are represented as comments in source code together with file naming conventions. For example +// +// // +build linux,386 darwin,!cgo +// // +build !purego +// +// Any terms provided in the filename can be thought of as an implicit extra +// constraint comment line. Collectively, these are referred to as +// ``constraints''. Each line is a ``constraint''. Within each constraint the +// space-separated terms are ``options'', and within that the comma-separated +// items are ``terms'' which may be negated with at most one exclaimation mark. +// +// These represent a boolean formulae. The constraints are evaluated as the AND +// of constraint lines; a constraint is evaluated as the OR of its options and +// an option is evaluated as the AND of its terms. Overall build constraints are +// a boolean formula that is an AND of ORs of ANDs. +// +// This level of complexity is rarely used in Go programs. Therefore this +// package aims to provide access to all these layers of nesting if required, +// but make it easy to forget about for basic use cases too. +package buildtags + +import ( + "errors" + "fmt" + "strings" + "unicode" +) + +// Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/go/build/doc.go#L73-L92 +// +// // A build constraint is evaluated as the OR of space-separated options; +// // each option evaluates as the AND of its comma-separated terms; +// // and each term is an alphanumeric word or, preceded by !, its negation. +// // That is, the build constraint: +// // +// // // +build linux,386 darwin,!cgo +// // +// // corresponds to the boolean formula: +// // +// // (linux AND 386) OR (darwin AND (NOT cgo)) +// // +// // A file may have multiple build constraints. The overall constraint is the AND +// // of the individual constraints. That is, the build constraints: +// // +// // // +build linux darwin +// // // +build 386 +// // +// // corresponds to the boolean formula: +// // +// // (linux OR darwin) AND 386 +// + +// Interface represents a build constraint. +type Interface interface { + ConstraintsConvertable + fmt.GoStringer + Evaluate(v map[string]bool) bool + Validate() error +} + +// ConstraintsConvertable can be converted to a Constraints object. +type ConstraintsConvertable interface { + ToConstraints() Constraints +} + +// ConstraintConvertable can be converted to a Constraint. +type ConstraintConvertable interface { + ToConstraint() Constraint +} + +// OptionConvertable can be converted to an Option. +type OptionConvertable interface { + ToOption() Option +} + +// Constraints represents the AND of a list of Constraint lines. +type Constraints []Constraint + +// And builds Constraints that will be true if all of its constraints are true. +func And(cs ...ConstraintConvertable) Constraints { + constraints := Constraints{} + for _, c := range cs { + constraints = append(constraints, c.ToConstraint()) + } + return constraints +} + +// ToConstraints returns cs. +func (cs Constraints) ToConstraints() Constraints { return cs } + +// Validate validates the constraints set. +func (cs Constraints) Validate() error { + for _, c := range cs { + if err := c.Validate(); err != nil { + return err + } + } + return nil +} + +// Evaluate the boolean formula represented by cs under the given assignment of +// tag values. This is the AND of the values of the constituent Constraints. +func (cs Constraints) Evaluate(v map[string]bool) bool { + r := true + for _, c := range cs { + r = r && c.Evaluate(v) + } + return r +} + +// GoString represents Constraints as +build comment lines. +func (cs Constraints) GoString() string { + s := "" + for _, c := range cs { + s += c.GoString() + } + return s +} + +// Constraint represents the OR of a list of Options. +type Constraint []Option + +// Any builds a Constraint that will be true if any of its options are true. +func Any(opts ...OptionConvertable) Constraint { + c := Constraint{} + for _, opt := range opts { + c = append(c, opt.ToOption()) + } + return c +} + +// ParseConstraint parses a space-separated list of options. +func ParseConstraint(expr string) (Constraint, error) { + c := Constraint{} + for _, field := range strings.Fields(expr) { + opt, err := ParseOption(field) + if err != nil { + return c, err + } + c = append(c, opt) + } + return c, nil +} + +// ToConstraints returns the list of constraints containing just c. +func (c Constraint) ToConstraints() Constraints { return Constraints{c} } + +// ToConstraint returns c. +func (c Constraint) ToConstraint() Constraint { return c } + +// Validate validates the constraint. +func (c Constraint) Validate() error { + for _, o := range c { + if err := o.Validate(); err != nil { + return err + } + } + return nil +} + +// Evaluate the boolean formula represented by c under the given assignment of +// tag values. This is the OR of the values of the constituent Options. +func (c Constraint) Evaluate(v map[string]bool) bool { + r := false + for _, o := range c { + r = r || o.Evaluate(v) + } + return r +} + +// GoString represents the Constraint as one +build comment line. +func (c Constraint) GoString() string { + s := "// +build" + for _, o := range c { + s += " " + o.GoString() + } + return s + "\n" +} + +// Option represents the AND of a list of Terms. +type Option []Term + +// Opt builds an Option from the list of Terms. +func Opt(terms ...Term) Option { + return Option(terms) +} + +// ParseOption parses a comma-separated list of terms. +func ParseOption(expr string) (Option, error) { + opt := Option{} + for _, t := range strings.Split(expr, ",") { + opt = append(opt, Term(t)) + } + return opt, opt.Validate() +} + +// ToConstraints returns Constraints containing just this option. +func (o Option) ToConstraints() Constraints { return o.ToConstraint().ToConstraints() } + +// ToConstraint returns a Constraint containing just this option. +func (o Option) ToConstraint() Constraint { return Constraint{o} } + +// ToOption returns o. +func (o Option) ToOption() Option { return o } + +// Validate validates o. +func (o Option) Validate() error { + for _, t := range o { + if err := t.Validate(); err != nil { + return fmt.Errorf("invalid term \"%s\": %s", t, err) + } + } + return nil +} + +// Evaluate the boolean formula represented by o under the given assignment of +// tag values. This is the AND of the values of the constituent Terms. +func (o Option) Evaluate(v map[string]bool) bool { + r := true + for _, t := range o { + r = r && t.Evaluate(v) + } + return r +} + +// GoString represents the Option as a comma-separated list of terms. +func (o Option) GoString() string { + var ts []string + for _, t := range o { + ts = append(ts, t.GoString()) + } + return strings.Join(ts, ",") +} + +// Term is an atomic term in a build constraint: an identifier or its negation. +type Term string + +// Not returns a term for the negation of ident. +func Not(ident string) Term { + return Term("!" + ident) +} + +// ToConstraints returns Constraints containing just this term. +func (t Term) ToConstraints() Constraints { return t.ToOption().ToConstraints() } + +// ToConstraint returns a Constraint containing just this term. +func (t Term) ToConstraint() Constraint { return t.ToOption().ToConstraint() } + +// ToOption returns an Option containing just this term. +func (t Term) ToOption() Option { return Option{t} } + +// IsNegated reports whether t is the negation of an identifier. +func (t Term) IsNegated() bool { return strings.HasPrefix(string(t), "!") } + +// Name returns the identifier for this term. +func (t Term) Name() string { + return strings.TrimPrefix(string(t), "!") +} + +// Validate the term. +func (t Term) Validate() error { + // Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/cmd/go/internal/imports/build.go#L110-L112 + // + // if strings.HasPrefix(name, "!!") { // bad syntax, reject always + // return false + // } + // + if strings.HasPrefix(string(t), "!!") { + return errors.New("at most one '!' allowed") + } + + if len(t.Name()) == 0 { + return errors.New("empty tag name") + } + + // Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/cmd/go/internal/imports/build.go#L121-L127 + // + // // Tags must be letters, digits, underscores or dots. + // // Unlike in Go identifiers, all digits are fine (e.g., "386"). + // for _, c := range name { + // if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { + // return false + // } + // } + // + for _, c := range t.Name() { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { + return fmt.Errorf("character '%c' disallowed in tags", c) + } + } + + return nil +} + +// Evaluate the term under the given set of identifier values. +func (t Term) Evaluate(v map[string]bool) bool { + return (t.Validate() == nil) && (v[t.Name()] == !t.IsNegated()) +} + +// GoString returns t. +func (t Term) GoString() string { return string(t) } + +// SetTags builds a set where the given list of identifiers are true. +func SetTags(idents ...string) map[string]bool { + v := map[string]bool{} + for _, ident := range idents { + v[ident] = true + } + return v +} diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/components.go b/vendor/github.com/mmcloughlin/avo/gotypes/components.go new file mode 100644 index 0000000..2206afa --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/components.go @@ -0,0 +1,253 @@ +package gotypes + +import ( + "errors" + "fmt" + "go/token" + "go/types" + "strconv" + + "github.com/mmcloughlin/avo/reg" + + "github.com/mmcloughlin/avo/operand" +) + +// Sizes provides type sizes used by the standard Go compiler on amd64. +var Sizes = types.SizesFor("gc", "amd64") + +// Basic represents a primitive/basic type at a given memory address. +type Basic struct { + Addr operand.Mem + Type *types.Basic +} + +// Component provides access to sub-components of a Go type. +type Component interface { + // When the component has no further sub-components, Resolve will return a + // reference to the components type and memory address. If there was an error + // during any previous calls to Component methods, they will be returned at + // resolution time. + Resolve() (*Basic, error) + + Dereference(r reg.Register) Component // dereference a pointer + Base() Component // base pointer of a string or slice + Len() Component // length of a string or slice + Cap() Component // capacity of a slice + Real() Component // real part of a complex value + Imag() Component // imaginary part of a complex value + Index(int) Component // index into an array + Field(string) Component // access a struct field +} + +// componenterr is an error that also provides a null implementation of the +// Component interface. This enables us to return an error from Component +// methods whilst also allowing method chaining to continue. +type componenterr string + +func errorf(format string, args ...interface{}) Component { + return componenterr(fmt.Sprintf(format, args...)) +} + +func (c componenterr) Error() string { return string(c) } +func (c componenterr) Resolve() (*Basic, error) { return nil, c } +func (c componenterr) Dereference(r reg.Register) Component { return c } +func (c componenterr) Base() Component { return c } +func (c componenterr) Len() Component { return c } +func (c componenterr) Cap() Component { return c } +func (c componenterr) Real() Component { return c } +func (c componenterr) Imag() Component { return c } +func (c componenterr) Index(int) Component { return c } +func (c componenterr) Field(string) Component { return c } + +type component struct { + typ types.Type + addr operand.Mem +} + +// NewComponent builds a component for the named type at the given address. +func NewComponent(t types.Type, addr operand.Mem) Component { + return &component{ + typ: t, + addr: addr, + } +} + +func (c *component) Resolve() (*Basic, error) { + b := toprimitive(c.typ) + if b == nil { + return nil, errors.New("component is not primitive") + } + return &Basic{ + Addr: c.addr, + Type: b, + }, nil +} + +func (c *component) Dereference(r reg.Register) Component { + p, ok := c.typ.Underlying().(*types.Pointer) + if !ok { + return errorf("not pointer type") + } + return NewComponent(p.Elem(), operand.Mem{Base: r}) +} + +// Reference: https://github.com/golang/go/blob/50bd1c4d4eb4fac8ddeb5f063c099daccfb71b26/src/reflect/value.go#L1800-L1804 +// +// type SliceHeader struct { +// Data uintptr +// Len int +// Cap int +// } +// +var slicehdroffsets = Sizes.Offsetsof([]*types.Var{ + types.NewField(token.NoPos, nil, "Data", types.Typ[types.Uintptr], false), + types.NewField(token.NoPos, nil, "Len", types.Typ[types.Int], false), + types.NewField(token.NoPos, nil, "Cap", types.Typ[types.Int], false), +}) + +func (c *component) Base() Component { + if !isslice(c.typ) && !isstring(c.typ) { + return errorf("only slices and strings have base pointers") + } + return c.sub("_base", int(slicehdroffsets[0]), types.Typ[types.Uintptr]) +} + +func (c *component) Len() Component { + if !isslice(c.typ) && !isstring(c.typ) { + return errorf("only slices and strings have length fields") + } + return c.sub("_len", int(slicehdroffsets[1]), types.Typ[types.Int]) +} + +func (c *component) Cap() Component { + if !isslice(c.typ) { + return errorf("only slices have capacity fields") + } + return c.sub("_cap", int(slicehdroffsets[2]), types.Typ[types.Int]) +} + +func (c *component) Real() Component { + if !iscomplex(c.typ) { + return errorf("only complex types have real values") + } + f := complextofloat(c.typ) + return c.sub("_real", 0, f) +} + +func (c *component) Imag() Component { + if !iscomplex(c.typ) { + return errorf("only complex types have imaginary values") + } + f := complextofloat(c.typ) + return c.sub("_imag", int(Sizes.Sizeof(f)), f) +} + +func (c *component) Index(i int) Component { + a, ok := c.typ.Underlying().(*types.Array) + if !ok { + return errorf("not array type") + } + if int64(i) >= a.Len() { + return errorf("array index out of bounds") + } + // Reference: https://github.com/golang/tools/blob/bcd4e47d02889ebbc25c9f4bf3d27e4124b0bf9d/go/analysis/passes/asmdecl/asmdecl.go#L482-L494 + // + // case asmArray: + // tu := t.Underlying().(*types.Array) + // elem := tu.Elem() + // // Calculate offset of each element array. + // fields := []*types.Var{ + // types.NewVar(token.NoPos, nil, "fake0", elem), + // types.NewVar(token.NoPos, nil, "fake1", elem), + // } + // offsets := arch.sizes.Offsetsof(fields) + // elemoff := int(offsets[1]) + // for i := 0; i < int(tu.Len()); i++ { + // cc = appendComponentsRecursive(arch, elem, cc, suffix+"_"+strconv.Itoa(i), i*elemoff) + // } + // + elem := a.Elem() + elemsize := int(Sizes.Sizeof(types.NewArray(elem, 2)) - Sizes.Sizeof(types.NewArray(elem, 1))) + return c.sub("_"+strconv.Itoa(i), i*elemsize, elem) +} + +func (c *component) Field(n string) Component { + s, ok := c.typ.Underlying().(*types.Struct) + if !ok { + return errorf("not struct type") + } + // Reference: https://github.com/golang/tools/blob/13ba8ad772dfbf0f451b5dd0679e9c5605afc05d/go/analysis/passes/asmdecl/asmdecl.go#L471-L480 + // + // case asmStruct: + // tu := t.Underlying().(*types.Struct) + // fields := make([]*types.Var, tu.NumFields()) + // for i := 0; i < tu.NumFields(); i++ { + // fields[i] = tu.Field(i) + // } + // offsets := arch.sizes.Offsetsof(fields) + // for i, f := range fields { + // cc = appendComponentsRecursive(arch, f.Type(), cc, suffix+"_"+f.Name(), off+int(offsets[i])) + // } + // + fields := make([]*types.Var, s.NumFields()) + for i := 0; i < s.NumFields(); i++ { + fields[i] = s.Field(i) + } + offsets := Sizes.Offsetsof(fields) + for i, f := range fields { + if f.Name() == n { + return c.sub("_"+n, int(offsets[i]), f.Type()) + } + } + return errorf("struct does not have field '%s'", n) +} + +func (c *component) sub(suffix string, offset int, t types.Type) *component { + s := *c + if s.addr.Symbol.Name != "" { + s.addr.Symbol.Name += suffix + } + s.addr = s.addr.Offset(offset) + s.typ = t + return &s +} + +func isslice(t types.Type) bool { + _, ok := t.Underlying().(*types.Slice) + return ok +} + +func isstring(t types.Type) bool { + b, ok := t.Underlying().(*types.Basic) + return ok && b.Kind() == types.String +} + +func iscomplex(t types.Type) bool { + b, ok := t.Underlying().(*types.Basic) + return ok && (b.Info()&types.IsComplex) != 0 +} + +func complextofloat(t types.Type) types.Type { + switch Sizes.Sizeof(t) { + case 16: + return types.Typ[types.Float64] + case 8: + return types.Typ[types.Float32] + } + panic("bad") +} + +// toprimitive determines whether t is primitive (cannot be reduced into +// components). If it is, it returns the basic type for t, otherwise returns +// nil. +func toprimitive(t types.Type) *types.Basic { + switch b := t.(type) { + case *types.Basic: + if (b.Info() & (types.IsString | types.IsComplex)) == 0 { + return b + } + case *types.Pointer: + return types.Typ[types.Uintptr] + } + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/doc.go b/vendor/github.com/mmcloughlin/avo/gotypes/doc.go new file mode 100644 index 0000000..fa8f078 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/doc.go @@ -0,0 +1,2 @@ +// Package gotypes provides helpers for interacting with Go types within avo functions. +package gotypes diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/signature.go b/vendor/github.com/mmcloughlin/avo/gotypes/signature.go new file mode 100644 index 0000000..e000020 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/signature.go @@ -0,0 +1,177 @@ +package gotypes + +import ( + "bytes" + "errors" + "fmt" + "go/token" + "go/types" + "strconv" + + "github.com/mmcloughlin/avo/operand" +) + +// Signature represents a Go function signature. +type Signature struct { + pkg *types.Package + sig *types.Signature + params *Tuple + results *Tuple +} + +// NewSignature constructs a Signature. +func NewSignature(pkg *types.Package, sig *types.Signature) *Signature { + s := &Signature{ + pkg: pkg, + sig: sig, + } + s.init() + return s +} + +// NewSignatureVoid builds the void signature "func()". +func NewSignatureVoid() *Signature { + return NewSignature(nil, types.NewSignature(nil, nil, nil, false)) +} + +// LookupSignature returns the signature of the named function in the provided package. +func LookupSignature(pkg *types.Package, name string) (*Signature, error) { + scope := pkg.Scope() + obj := scope.Lookup(name) + if obj == nil { + return nil, fmt.Errorf("could not find function \"%s\"", name) + } + s, ok := obj.Type().(*types.Signature) + if !ok { + return nil, fmt.Errorf("object \"%s\" does not have signature type", name) + } + return NewSignature(pkg, s), nil +} + +// ParseSignature builds a Signature by parsing a Go function type expression. +// The function type must reference builtin types only; see +// ParseSignatureInPackage if custom types are required. +func ParseSignature(expr string) (*Signature, error) { + return ParseSignatureInPackage(nil, expr) +} + +// ParseSignatureInPackage builds a Signature by parsing a Go function type +// expression. The expression may reference types in the provided package. +func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error) { + tv, err := types.Eval(token.NewFileSet(), pkg, token.NoPos, expr) + if err != nil { + return nil, err + } + if tv.Value != nil { + return nil, errors.New("signature expression should have nil value") + } + s, ok := tv.Type.(*types.Signature) + if !ok { + return nil, errors.New("provided type is not a function signature") + } + return NewSignature(pkg, s), nil +} + +// Params returns the function signature argument types. +func (s *Signature) Params() *Tuple { return s.params } + +// Results returns the function return types. +func (s *Signature) Results() *Tuple { return s.results } + +// Bytes returns the total size of the function arguments and return values. +func (s *Signature) Bytes() int { return s.Params().Bytes() + s.Results().Bytes() } + +// String writes Signature as a string. This does not include the "func" keyword. +func (s *Signature) String() string { + var buf bytes.Buffer + types.WriteSignature(&buf, s.sig, func(pkg *types.Package) string { + if pkg == s.pkg { + return "" + } + return pkg.Name() + }) + return buf.String() +} + +func (s *Signature) init() { + p := s.sig.Params() + r := s.sig.Results() + + // Compute parameter offsets. + vs := tuplevars(p) + vs = append(vs, types.NewParam(token.NoPos, nil, "sentinel", types.Typ[types.Uint64])) + paramsoffsets := Sizes.Offsetsof(vs) + paramssize := paramsoffsets[p.Len()] + s.params = newTuple(p, paramsoffsets, paramssize, "arg") + + // Result offsets. + vs = tuplevars(r) + resultsoffsets := Sizes.Offsetsof(vs) + var resultssize int64 + if n := len(vs); n > 0 { + resultssize = resultsoffsets[n-1] + Sizes.Sizeof(vs[n-1].Type()) + } + for i := range resultsoffsets { + resultsoffsets[i] += paramssize + } + s.results = newTuple(r, resultsoffsets, resultssize, "ret") +} + +// Tuple represents a tuple of variables, such as function arguments or results. +type Tuple struct { + components []Component + byname map[string]Component + size int +} + +func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string) *Tuple { + tuple := &Tuple{ + byname: map[string]Component{}, + size: int(size), + } + for i := 0; i < t.Len(); i++ { + v := t.At(i) + name := v.Name() + if name == "" { + name = defaultprefix + if i > 0 { + name += strconv.Itoa(i) + } + } + addr := operand.NewParamAddr(name, int(offsets[i])) + c := NewComponent(v.Type(), addr) + tuple.components = append(tuple.components, c) + if v.Name() != "" { + tuple.byname[v.Name()] = c + } + } + return tuple +} + +// Lookup returns the variable with the given name. +func (t *Tuple) Lookup(name string) Component { + e := t.byname[name] + if e == nil { + return errorf("unknown variable \"%s\"", name) + } + return e +} + +// At returns the variable at index i. +func (t *Tuple) At(i int) Component { + if i >= len(t.components) { + return errorf("index out of range") + } + return t.components[i] +} + +// Bytes returns the size of the Tuple. This may include additional padding. +func (t *Tuple) Bytes() int { return t.size } + +func tuplevars(t *types.Tuple) []*types.Var { + vs := make([]*types.Var, t.Len()) + for i := 0; i < t.Len(); i++ { + vs[i] = t.At(i) + } + return vs +} diff --git a/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go b/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go new file mode 100644 index 0000000..410895c --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go @@ -0,0 +1,60 @@ +// Package prnt provides common functionality for code generators. +package prnt + +import ( + "bytes" + "fmt" + "io" + "strings" +) + +// Generator provides convenience methods for code generators. In particular it +// provides fmt-like methods which print to an internal buffer. It also allows +// any errors to be stored so they can be checked at the end, rather than having +// error checks obscuring the code generation. +type Generator struct { + buf bytes.Buffer + err error +} + +// Raw provides direct access to the underlying output stream. +func (g *Generator) Raw() io.Writer { + return &g.buf +} + +// Printf prints to the internal buffer. +func (g *Generator) Printf(format string, args ...interface{}) { + if g.err != nil { + return + } + _, err := fmt.Fprintf(&g.buf, format, args...) + g.AddError(err) +} + +// NL prints a new line. +func (g *Generator) NL() { + g.Printf("\n") +} + +// Comment writes comment lines prefixed with "// ". +func (g *Generator) Comment(lines ...string) { + for _, line := range lines { + line = strings.TrimSpace("// " + line) + g.Printf("%s\n", line) + } +} + +// AddError records an error in code generation. The first non-nil error will +// prevent printing operations from writing anything else, and the error will be +// returned from Result(). +func (g *Generator) AddError(err error) { + if err != nil && g.err == nil { + g.err = err + } +} + +// Result returns the printed bytes. If any error was recorded with AddError +// during code generation, the first such error will be returned here. +func (g *Generator) Result() ([]byte, error) { + return g.buf.Bytes(), g.err +} diff --git a/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go b/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go new file mode 100644 index 0000000..1d327d9 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go @@ -0,0 +1,73 @@ +// Package stack provides helpers for querying the callstack. +package stack + +import ( + "path" + "runtime" + "strings" +) + +// Frames returns at most max callstack Frames, starting with its caller and +// skipping skip Frames. +func Frames(skip, max int) []runtime.Frame { + pc := make([]uintptr, max) + n := runtime.Callers(skip+2, pc) + if n == 0 { + return nil + } + pc = pc[:n] + frames := runtime.CallersFrames(pc) + var fs []runtime.Frame + for { + f, more := frames.Next() + fs = append(fs, f) + if !more { + break + } + } + return fs +} + +// Match returns the first stack frame for which the predicate function returns +// true. Returns nil if no match is found. Starts matching after skip frames, +// starting with its caller. +func Match(skip int, predicate func(runtime.Frame) bool) *runtime.Frame { + i, n := skip+1, 16 + for { + fs := Frames(i, n) + for j, f := range fs { + if predicate(f) { + return &fs[j] + } + } + if len(fs) < n { + break + } + i += n + } + return nil +} + +// Main returns the main() function Frame. +func Main() *runtime.Frame { + return Match(1, func(f runtime.Frame) bool { + return f.Function == "main.main" + }) +} + +// ExternalCaller returns the first frame outside the callers package. +func ExternalCaller() *runtime.Frame { + var first *runtime.Frame + return Match(1, func(f runtime.Frame) bool { + if first == nil { + first = &f + } + return pkg(first.Function) != pkg(f.Function) + }) +} + +func pkg(ident string) string { + dir, name := path.Split(ident) + parts := strings.Split(name, ".") + return dir + parts[0] +} diff --git a/vendor/github.com/mmcloughlin/avo/ir/doc.go b/vendor/github.com/mmcloughlin/avo/ir/doc.go new file mode 100644 index 0000000..de02f46 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/ir/doc.go @@ -0,0 +1,2 @@ +// Package ir provides the intermediate representation of avo programs. +package ir diff --git a/vendor/github.com/mmcloughlin/avo/ir/ir.go b/vendor/github.com/mmcloughlin/avo/ir/ir.go new file mode 100644 index 0000000..6fb9216 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/ir/ir.go @@ -0,0 +1,355 @@ +package ir + +import ( + "errors" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// Node is a part of a Function. +type Node interface { + node() +} + +// Label within a function. +type Label string + +func (l Label) node() {} + +// Comment represents a multi-line comment. +type Comment struct { + Lines []string +} + +func (c *Comment) node() {} + +// NewComment builds a Comment consisting of the provided lines. +func NewComment(lines ...string) *Comment { + return &Comment{ + Lines: lines, + } +} + +// Instruction is a single instruction in a function. +type Instruction struct { + Opcode string + Operands []operand.Op + + Inputs []operand.Op + Outputs []operand.Op + + IsTerminal bool + IsBranch bool + IsConditional bool + CancellingInputs bool + + // ISA is the list of required instruction set extensions. + ISA []string + + // CFG. + Pred []*Instruction + Succ []*Instruction + + // LiveIn/LiveOut are sets of live register IDs pre/post execution. + LiveIn reg.MaskSet + LiveOut reg.MaskSet +} + +func (i *Instruction) node() {} + +// IsUnconditionalBranch reports whether i is an unconditional branch. +func (i Instruction) IsUnconditionalBranch() bool { + return i.IsBranch && !i.IsConditional +} + +// TargetLabel returns the label referenced by this instruction. Returns nil if +// no label is referenced. +func (i Instruction) TargetLabel() *Label { + if !i.IsBranch { + return nil + } + if len(i.Operands) == 0 { + return nil + } + if ref, ok := i.Operands[0].(operand.LabelRef); ok { + lbl := Label(ref) + return &lbl + } + return nil +} + +// Registers returns all registers involved in the instruction. +func (i Instruction) Registers() []reg.Register { + var rs []reg.Register + for _, op := range i.Operands { + rs = append(rs, operand.Registers(op)...) + } + return rs +} + +// InputRegisters returns all registers read by this instruction. +func (i Instruction) InputRegisters() []reg.Register { + var rs []reg.Register + for _, op := range i.Inputs { + rs = append(rs, operand.Registers(op)...) + } + if i.CancellingInputs && rs[0] == rs[1] { + rs = []reg.Register{} + } + for _, op := range i.Outputs { + if operand.IsMem(op) { + rs = append(rs, operand.Registers(op)...) + } + } + return rs +} + +// OutputRegisters returns all registers written by this instruction. +func (i Instruction) OutputRegisters() []reg.Register { + var rs []reg.Register + for _, op := range i.Outputs { + if r, ok := op.(reg.Register); ok { + rs = append(rs, r) + } + } + return rs +} + +// Section is a part of a file. +type Section interface { + section() +} + +// File represents an assembly file. +type File struct { + Constraints buildtags.Constraints + Includes []string + Sections []Section +} + +// NewFile initializes an empty file. +func NewFile() *File { + return &File{} +} + +// AddSection appends a Section to the file. +func (f *File) AddSection(s Section) { + f.Sections = append(f.Sections, s) +} + +// Functions returns all functions in the file. +func (f *File) Functions() []*Function { + var fns []*Function + for _, s := range f.Sections { + if fn, ok := s.(*Function); ok { + fns = append(fns, fn) + } + } + return fns +} + +// Pragma represents a function compiler directive. +type Pragma struct { + Directive string + Arguments []string +} + +// Function represents an assembly function. +type Function struct { + Name string + Attributes attr.Attribute + Pragmas []Pragma + Doc []string + Signature *gotypes.Signature + LocalSize int + + Nodes []Node + + // LabelTarget maps from label name to the following instruction. + LabelTarget map[Label]*Instruction + + // Register allocation. + Allocation reg.Allocation + + // ISA is the list of required instruction set extensions. + ISA []string +} + +func (f *Function) section() {} + +// NewFunction builds an empty function of the given name. +func NewFunction(name string) *Function { + return &Function{ + Name: name, + Signature: gotypes.NewSignatureVoid(), + } +} + +// AddPragma adds a pragma to this function. +func (f *Function) AddPragma(directive string, args ...string) { + f.Pragmas = append(f.Pragmas, Pragma{ + Directive: directive, + Arguments: args, + }) +} + +// SetSignature sets the function signature. +func (f *Function) SetSignature(s *gotypes.Signature) { + f.Signature = s +} + +// AllocLocal allocates size bytes in this function's stack. +// Returns a reference to the base pointer for the newly allocated region. +func (f *Function) AllocLocal(size int) operand.Mem { + ptr := operand.NewStackAddr(f.LocalSize) + f.LocalSize += size + return ptr +} + +// AddInstruction appends an instruction to f. +func (f *Function) AddInstruction(i *Instruction) { + f.AddNode(i) +} + +// AddLabel appends a label to f. +func (f *Function) AddLabel(l Label) { + f.AddNode(l) +} + +// AddComment adds comment lines to f. +func (f *Function) AddComment(lines ...string) { + f.AddNode(NewComment(lines...)) +} + +// AddNode appends a Node to f. +func (f *Function) AddNode(n Node) { + f.Nodes = append(f.Nodes, n) +} + +// Instructions returns just the list of instruction nodes. +func (f *Function) Instructions() []*Instruction { + var is []*Instruction + for _, n := range f.Nodes { + i, ok := n.(*Instruction) + if ok { + is = append(is, i) + } + } + return is +} + +// Labels returns just the list of label nodes. +func (f *Function) Labels() []Label { + var lbls []Label + for _, n := range f.Nodes { + lbl, ok := n.(Label) + if ok { + lbls = append(lbls, lbl) + } + } + return lbls +} + +// Stub returns the Go function declaration. +func (f *Function) Stub() string { + return "func " + f.Name + f.Signature.String() +} + +// FrameBytes returns the size of the stack frame in bytes. +func (f *Function) FrameBytes() int { + return f.LocalSize +} + +// ArgumentBytes returns the size of the arguments in bytes. +func (f *Function) ArgumentBytes() int { + return f.Signature.Bytes() +} + +// Datum represents a data element at a particular offset of a data section. +type Datum struct { + Offset int + Value operand.Constant +} + +// NewDatum builds a Datum from the given constant. +func NewDatum(offset int, v operand.Constant) Datum { + return Datum{ + Offset: offset, + Value: v, + } +} + +// Interval returns the range of bytes this datum will occupy within its section. +func (d Datum) Interval() (int, int) { + return d.Offset, d.Offset + d.Value.Bytes() +} + +// Overlaps returns true +func (d Datum) Overlaps(other Datum) bool { + s, e := d.Interval() + so, eo := other.Interval() + return !(eo <= s || e <= so) +} + +// Global represents a DATA section. +type Global struct { + Symbol operand.Symbol + Attributes attr.Attribute + Data []Datum + Size int +} + +// NewGlobal constructs an empty DATA section. +func NewGlobal(sym operand.Symbol) *Global { + return &Global{ + Symbol: sym, + } +} + +// NewStaticGlobal is a convenience for building a static DATA section. +func NewStaticGlobal(name string) *Global { + return NewGlobal(operand.NewStaticSymbol(name)) +} + +func (g *Global) section() {} + +// Base returns a pointer to the start of the data section. +func (g *Global) Base() operand.Mem { + return operand.NewDataAddr(g.Symbol, 0) +} + +// Grow ensures that the data section has at least the given size. +func (g *Global) Grow(size int) { + if g.Size < size { + g.Size = size + } +} + +// AddDatum adds d to this data section, growing it if necessary. Errors if the datum overlaps with existing data. +func (g *Global) AddDatum(d Datum) error { + for _, other := range g.Data { + if d.Overlaps(other) { + return errors.New("overlaps existing datum") + } + } + g.add(d) + return nil +} + +// Append the constant to the end of the data section. +func (g *Global) Append(v operand.Constant) { + g.add(Datum{ + Offset: g.Size, + Value: v, + }) +} + +func (g *Global) add(d Datum) { + _, end := d.Interval() + g.Grow(end) + g.Data = append(g.Data, d) +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/checks.go b/vendor/github.com/mmcloughlin/avo/operand/checks.go new file mode 100644 index 0000000..2585479 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/checks.go @@ -0,0 +1,247 @@ +package operand + +import "github.com/mmcloughlin/avo/reg" + +// Pure type assertion checks: + +// IsRegister returns whether op has type reg.Register. +func IsRegister(op Op) bool { _, ok := op.(reg.Register); return ok } + +// IsMem returns whether op has type Mem. +func IsMem(op Op) bool { _, ok := op.(Mem); return ok } + +// IsRel returns whether op has type Rel. +func IsRel(op Op) bool { _, ok := op.(Rel); return ok } + +// Checks corresponding to specific operand types in the Intel Manual: + +// Is1 returns true if op is the immediate constant 1. +func Is1(op Op) bool { + i, ok := op.(U8) + return ok && i == 1 +} + +// Is3 returns true if op is the immediate constant 3. +func Is3(op Op) bool { + i, ok := op.(U8) + return ok && i == 3 +} + +// IsIMM2U returns true if op is a 2-bit unsigned immediate (less than 4). +func IsIMM2U(op Op) bool { + i, ok := op.(U8) + return ok && i < 4 +} + +// IsIMM8 returns true is op is an 8-bit immediate. +func IsIMM8(op Op) bool { + _, ok := op.(U8) + return ok +} + +// IsIMM16 returns true is op is a 16-bit immediate. +func IsIMM16(op Op) bool { + _, ok := op.(U16) + return ok +} + +// IsIMM32 returns true is op is a 32-bit immediate. +func IsIMM32(op Op) bool { + _, ok := op.(U32) + return ok +} + +// IsIMM64 returns true is op is a 64-bit immediate. +func IsIMM64(op Op) bool { + _, ok := op.(U64) + return ok +} + +// IsAL returns true if op is the AL register. +func IsAL(op Op) bool { + return op == reg.AL +} + +// IsCL returns true if op is the CL register. +func IsCL(op Op) bool { + return op == reg.CL +} + +// IsAX returns true if op is the 16-bit AX register. +func IsAX(op Op) bool { + return op == reg.AX +} + +// IsEAX returns true if op is the 32-bit EAX register. +func IsEAX(op Op) bool { + return op == reg.EAX +} + +// IsRAX returns true if op is the 64-bit RAX register. +func IsRAX(op Op) bool { + return op == reg.RAX +} + +// IsR8 returns true if op is an 8-bit general-purpose register. +func IsR8(op Op) bool { + return IsGP(op, 1) +} + +// IsR16 returns true if op is a 16-bit general-purpose register. +func IsR16(op Op) bool { + return IsGP(op, 2) +} + +// IsR32 returns true if op is a 32-bit general-purpose register. +func IsR32(op Op) bool { + return IsGP(op, 4) +} + +// IsR64 returns true if op is a 64-bit general-purpose register. +func IsR64(op Op) bool { + return IsGP(op, 8) +} + +// IsPseudo returns true if op is a pseudo register. +func IsPseudo(op Op) bool { + return IsRegisterKind(op, reg.KindPseudo) +} + +// IsGP returns true if op is a general-purpose register of size n bytes. +func IsGP(op Op, n uint) bool { + return IsRegisterKindSize(op, reg.KindGP, n) +} + +// IsXMM0 returns true if op is the X0 register. +func IsXMM0(op Op) bool { + return op == reg.X0 +} + +// IsXMM returns true if op is a 128-bit XMM register. +func IsXMM(op Op) bool { + return IsRegisterKindSize(op, reg.KindVector, 16) +} + +// IsYMM returns true if op is a 256-bit YMM register. +func IsYMM(op Op) bool { + return IsRegisterKindSize(op, reg.KindVector, 32) +} + +// IsRegisterKindSize returns true if op is a register of the given kind and size in bytes. +func IsRegisterKindSize(op Op, k reg.Kind, n uint) bool { + r, ok := op.(reg.Register) + return ok && r.Kind() == k && r.Size() == n +} + +// IsRegisterKind returns true if op is a register of the given kind. +func IsRegisterKind(op Op, k reg.Kind) bool { + r, ok := op.(reg.Register) + return ok && r.Kind() == k +} + +// IsM returns true if op is a 16-, 32- or 64-bit memory operand. +func IsM(op Op) bool { + // TODO(mbm): confirm "m" check is defined correctly + // Intel manual: "A 16-, 32- or 64-bit operand in memory." + return IsM16(op) || IsM32(op) || IsM64(op) +} + +// IsM8 returns true if op is an 8-bit memory operand. +func IsM8(op Op) bool { + // TODO(mbm): confirm "m8" check is defined correctly + // Intel manual: "A byte operand in memory, usually expressed as a variable or + // array name, but pointed to by the DS:(E)SI or ES:(E)DI registers. In 64-bit + // mode, it is pointed to by the RSI or RDI registers." + return IsMSize(op, 1) +} + +// IsM16 returns true if op is a 16-bit memory operand. +func IsM16(op Op) bool { + return IsMSize(op, 2) +} + +// IsM32 returns true if op is a 16-bit memory operand. +func IsM32(op Op) bool { + return IsMSize(op, 4) +} + +// IsM64 returns true if op is a 64-bit memory operand. +func IsM64(op Op) bool { + return IsMSize(op, 8) +} + +// IsMSize returns true if op is a memory operand using general-purpose address +// registers of the given size in bytes. +func IsMSize(op Op, n uint) bool { + // TODO(mbm): should memory operands have a size attribute as well? + // TODO(mbm): m8,m16,m32,m64 checks do not actually check size + m, ok := op.(Mem) + return ok && IsMReg(m.Base) && (m.Index == nil || IsMReg(m.Index)) +} + +// IsMReg returns true if op is a register that can be used in a memory operand. +func IsMReg(op Op) bool { + return IsPseudo(op) || IsRegisterKind(op, reg.KindGP) +} + +// IsM128 returns true if op is a 128-bit memory operand. +func IsM128(op Op) bool { + // TODO(mbm): should "m128" be the same as "m64"? + return IsM64(op) +} + +// IsM256 returns true if op is a 256-bit memory operand. +func IsM256(op Op) bool { + // TODO(mbm): should "m256" be the same as "m64"? + return IsM64(op) +} + +// IsVM32X returns true if op is a vector memory operand with 32-bit XMM index. +func IsVM32X(op Op) bool { + return IsVmx(op) +} + +// IsVM64X returns true if op is a vector memory operand with 64-bit XMM index. +func IsVM64X(op Op) bool { + return IsVmx(op) +} + +// IsVmx returns true if op is a vector memory operand with XMM index. +func IsVmx(op Op) bool { + return isvm(op, IsXMM) +} + +// IsVM32Y returns true if op is a vector memory operand with 32-bit YMM index. +func IsVM32Y(op Op) bool { + return IsVmy(op) +} + +// IsVM64Y returns true if op is a vector memory operand with 64-bit YMM index. +func IsVM64Y(op Op) bool { + return IsVmy(op) +} + +// IsVmy returns true if op is a vector memory operand with YMM index. +func IsVmy(op Op) bool { + return isvm(op, IsYMM) +} + +func isvm(op Op, idx func(Op) bool) bool { + m, ok := op.(Mem) + return ok && IsR64(m.Base) && idx(m.Index) +} + +// IsREL8 returns true if op is an 8-bit offset relative to instruction pointer. +func IsREL8(op Op) bool { + r, ok := op.(Rel) + return ok && r == Rel(int8(r)) +} + +// IsREL32 returns true if op is an offset relative to instruction pointer, or a +// label reference. +func IsREL32(op Op) bool { + // TODO(mbm): should labels be considered separately? + _, rel := op.(Rel) + _, label := op.(LabelRef) + return rel || label +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/const.go b/vendor/github.com/mmcloughlin/avo/operand/const.go new file mode 100644 index 0000000..b2c6a6f --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/const.go @@ -0,0 +1,36 @@ +package operand + +import "fmt" + +// Constant represents a constant literal. +type Constant interface { + Op + Bytes() int + constant() +} + +//go:generate go run make_const.go -output zconst.go + +// String is a string constant. +type String string + +// Asm returns an assembly syntax representation of the string s. +func (s String) Asm() string { return fmt.Sprintf("$%q", s) } + +// Bytes returns the length of s. +func (s String) Bytes() int { return len(s) } + +func (s String) constant() {} + +// Imm returns an unsigned integer constant with size guessed from x. +func Imm(x uint64) Constant { + switch { + case uint64(uint8(x)) == x: + return U8(x) + case uint64(uint16(x)) == x: + return U16(x) + case uint64(uint32(x)) == x: + return U32(x) + } + return U64(x) +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/doc.go b/vendor/github.com/mmcloughlin/avo/operand/doc.go new file mode 100644 index 0000000..51c44df --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/doc.go @@ -0,0 +1,2 @@ +// Package operand provides types for instruction operands. +package operand diff --git a/vendor/github.com/mmcloughlin/avo/operand/types.go b/vendor/github.com/mmcloughlin/avo/operand/types.go new file mode 100644 index 0000000..878425e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/types.go @@ -0,0 +1,151 @@ +package operand + +import ( + "fmt" + + "github.com/mmcloughlin/avo/reg" +) + +// Op is an operand. +type Op interface { + Asm() string +} + +// Symbol represents a symbol name. +type Symbol struct { + Name string + Static bool // only visible in current source file +} + +// NewStaticSymbol builds a static Symbol. Static symbols are only visible in the current source file. +func NewStaticSymbol(name string) Symbol { + return Symbol{Name: name, Static: true} +} + +func (s Symbol) String() string { + n := s.Name + if s.Static { + n += "<>" + } + return n +} + +// Mem represents a memory reference. +type Mem struct { + Symbol Symbol + Disp int + Base reg.Register + Index reg.Register + Scale uint8 +} + +// NewParamAddr is a convenience to build a Mem operand pointing to a function +// parameter, which is a named offset from the frame pointer pseudo register. +func NewParamAddr(name string, offset int) Mem { + return Mem{ + Symbol: Symbol{ + Name: name, + Static: false, + }, + Disp: offset, + Base: reg.FramePointer, + } +} + +// NewStackAddr returns a memory reference relative to the stack pointer. +func NewStackAddr(offset int) Mem { + return Mem{ + Disp: offset, + Base: reg.StackPointer, + } +} + +// NewDataAddr returns a memory reference relative to the named data symbol. +func NewDataAddr(sym Symbol, offset int) Mem { + return Mem{ + Symbol: sym, + Disp: offset, + Base: reg.StaticBase, + } +} + +// Offset returns a reference to m plus idx bytes. +func (m Mem) Offset(idx int) Mem { + a := m + a.Disp += idx + return a +} + +// Idx returns a new memory reference with (Index, Scale) set to (r, s). +func (m Mem) Idx(r reg.Register, s uint8) Mem { + a := m + a.Index = r + a.Scale = s + return a +} + +// Asm returns an assembly syntax representation of m. +func (m Mem) Asm() string { + a := m.Symbol.String() + if a != "" { + a += fmt.Sprintf("%+d", m.Disp) + } else if m.Disp != 0 { + a += fmt.Sprintf("%d", m.Disp) + } + if m.Base != nil { + a += fmt.Sprintf("(%s)", m.Base.Asm()) + } + if m.Index != nil && m.Scale != 0 { + a += fmt.Sprintf("(%s*%d)", m.Index.Asm(), m.Scale) + } + return a +} + +// Rel is an offset relative to the instruction pointer. +type Rel int32 + +// Asm returns an assembly syntax representation of r. +func (r Rel) Asm() string { + return fmt.Sprintf(".%+d", r) +} + +// LabelRef is a reference to a label. +type LabelRef string + +// Asm returns an assembly syntax representation of l. +func (l LabelRef) Asm() string { + return string(l) +} + +// Registers returns the list of all operands involved in the given operand. +func Registers(op Op) []reg.Register { + switch op := op.(type) { + case reg.Register: + return []reg.Register{op} + case Mem: + var r []reg.Register + if op.Base != nil { + r = append(r, op.Base) + } + if op.Index != nil { + r = append(r, op.Index) + } + return r + case Constant, Rel, LabelRef: + return nil + } + panic("unknown operand type") +} + +// ApplyAllocation returns an operand with allocated registers replaced. Registers missing from the allocation are left alone. +func ApplyAllocation(op Op, a reg.Allocation) Op { + switch op := op.(type) { + case reg.Register: + return a.LookupRegisterDefault(op) + case Mem: + op.Base = a.LookupRegisterDefault(op.Base) + op.Index = a.LookupRegisterDefault(op.Index) + return op + } + return op +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/zconst.go b/vendor/github.com/mmcloughlin/avo/operand/zconst.go new file mode 100644 index 0000000..324b4a9 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/zconst.go @@ -0,0 +1,75 @@ +// Code generated by make_const.go. DO NOT EDIT. + +package operand + +import "fmt" + +// I8 is a 8-bit signed integer constant. +type I8 int8 + +func (i I8) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I8) Bytes() int { return 1 } +func (i I8) constant() {} + +// U8 is a 8-bit unsigned integer constant. +type U8 uint8 + +func (u U8) Asm() string { return fmt.Sprintf("$%#02x", u) } +func (u U8) Bytes() int { return 1 } +func (u U8) constant() {} + +// I16 is a 16-bit signed integer constant. +type I16 int16 + +func (i I16) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I16) Bytes() int { return 2 } +func (i I16) constant() {} + +// U16 is a 16-bit unsigned integer constant. +type U16 uint16 + +func (u U16) Asm() string { return fmt.Sprintf("$%#04x", u) } +func (u U16) Bytes() int { return 2 } +func (u U16) constant() {} + +// F32 is a 32-bit floating point constant. +type F32 float32 + +func (f F32) Asm() string { return fmt.Sprintf("$(%#v)", f) } +func (f F32) Bytes() int { return 4 } +func (f F32) constant() {} + +// I32 is a 32-bit signed integer constant. +type I32 int32 + +func (i I32) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I32) Bytes() int { return 4 } +func (i I32) constant() {} + +// U32 is a 32-bit unsigned integer constant. +type U32 uint32 + +func (u U32) Asm() string { return fmt.Sprintf("$%#08x", u) } +func (u U32) Bytes() int { return 4 } +func (u U32) constant() {} + +// F64 is a 64-bit floating point constant. +type F64 float64 + +func (f F64) Asm() string { return fmt.Sprintf("$(%#v)", f) } +func (f F64) Bytes() int { return 8 } +func (f F64) constant() {} + +// I64 is a 64-bit signed integer constant. +type I64 int64 + +func (i I64) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I64) Bytes() int { return 8 } +func (i I64) constant() {} + +// U64 is a 64-bit unsigned integer constant. +type U64 uint64 + +func (u U64) Asm() string { return fmt.Sprintf("$%#016x", u) } +func (u U64) Bytes() int { return 8 } +func (u U64) constant() {} diff --git a/vendor/github.com/mmcloughlin/avo/pass/alloc.go b/vendor/github.com/mmcloughlin/avo/pass/alloc.go new file mode 100644 index 0000000..fc7773a --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/alloc.go @@ -0,0 +1,190 @@ +package pass + +import ( + "errors" + "math" + "sort" + + "github.com/mmcloughlin/avo/reg" +) + +// edge is an edge of the interference graph, indicating that registers X and Y +// must be in non-conflicting registers. +type edge struct { + X, Y reg.ID +} + +// Allocator is a graph-coloring register allocator. +type Allocator struct { + registers []reg.ID + allocation reg.Allocation + edges []*edge + possible map[reg.ID][]reg.ID +} + +// NewAllocator builds an allocator for the given physical registers. +func NewAllocator(rs []reg.Physical) (*Allocator, error) { + // Set of IDs, excluding restricted registers. + idset := map[reg.ID]bool{} + for _, r := range rs { + if (r.Info() & reg.Restricted) != 0 { + continue + } + idset[r.ID()] = true + } + + if len(idset) == 0 { + return nil, errors.New("no allocatable registers") + } + + // Produce slice of unique register IDs. + var ids []reg.ID + for id := range idset { + ids = append(ids, id) + } + sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) + + return &Allocator{ + registers: ids, + allocation: reg.NewEmptyAllocation(), + possible: map[reg.ID][]reg.ID{}, + }, nil +} + +// NewAllocatorForKind builds an allocator for the given kind of registers. +func NewAllocatorForKind(k reg.Kind) (*Allocator, error) { + f := reg.FamilyOfKind(k) + if f == nil { + return nil, errors.New("unknown register family") + } + return NewAllocator(f.Registers()) +} + +// AddInterferenceSet records that r interferes with every register in s. Convenience wrapper around AddInterference. +func (a *Allocator) AddInterferenceSet(r reg.Register, s reg.MaskSet) { + for id, mask := range s { + if (r.Mask() & mask) != 0 { + a.AddInterference(r.ID(), id) + } + } +} + +// AddInterference records that x and y must be assigned to non-conflicting physical registers. +func (a *Allocator) AddInterference(x, y reg.ID) { + a.Add(x) + a.Add(y) + a.edges = append(a.edges, &edge{X: x, Y: y}) +} + +// Add adds a register to be allocated. Does nothing if the register has already been added. +func (a *Allocator) Add(v reg.ID) { + if !v.IsVirtual() { + return + } + if _, found := a.possible[v]; found { + return + } + a.possible[v] = a.possibleregisters(v) +} + +// Allocate allocates physical registers. +func (a *Allocator) Allocate() (reg.Allocation, error) { + for { + if err := a.update(); err != nil { + return nil, err + } + + if a.remaining() == 0 { + break + } + + v := a.mostrestricted() + if err := a.alloc(v); err != nil { + return nil, err + } + } + return a.allocation, nil +} + +// update possible allocations based on edges. +func (a *Allocator) update() error { + var rem []*edge + for _, e := range a.edges { + x := a.allocation.LookupDefault(e.X) + y := a.allocation.LookupDefault(e.Y) + switch { + case x.IsVirtual() && y.IsVirtual(): + rem = append(rem, e) + continue + case x.IsPhysical() && y.IsPhysical(): + if x == y { + return errors.New("impossible register allocation") + } + case x.IsPhysical() && y.IsVirtual(): + a.discardconflicting(y, x) + case x.IsVirtual() && y.IsPhysical(): + a.discardconflicting(x, y) + default: + panic("unreachable") + } + } + a.edges = rem + + return nil +} + +// mostrestricted returns the virtual register with the least possibilities. +func (a *Allocator) mostrestricted() reg.ID { + n := int(math.MaxInt32) + var v reg.ID + for w, p := range a.possible { + // On a tie, choose the smallest ID in numeric order. This avoids + // non-deterministic allocations due to map iteration order. + if len(p) < n || (len(p) == n && w < v) { + n = len(p) + v = w + } + } + return v +} + +// discardconflicting removes registers from vs possible list that conflict with p. +func (a *Allocator) discardconflicting(v, p reg.ID) { + a.possible[v] = filterregisters(a.possible[v], func(r reg.ID) bool { + return r != p + }) +} + +// alloc attempts to allocate a register to v. +func (a *Allocator) alloc(v reg.ID) error { + ps := a.possible[v] + if len(ps) == 0 { + return errors.New("failed to allocate registers") + } + p := ps[0] + a.allocation[v] = p + delete(a.possible, v) + return nil +} + +// remaining returns the number of unallocated registers. +func (a *Allocator) remaining() int { + return len(a.possible) +} + +// possibleregisters returns all allocate-able registers for the given virtual. +func (a *Allocator) possibleregisters(v reg.ID) []reg.ID { + return filterregisters(a.registers, func(r reg.ID) bool { + return v.Kind() == r.Kind() + }) +} + +func filterregisters(in []reg.ID, predicate func(reg.ID) bool) []reg.ID { + var rs []reg.ID + for _, r := range in { + if predicate(r) { + rs = append(rs, r) + } + } + return rs +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/cfg.go b/vendor/github.com/mmcloughlin/avo/pass/cfg.go new file mode 100644 index 0000000..d5f6ea4 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/cfg.go @@ -0,0 +1,81 @@ +package pass + +import ( + "errors" + "fmt" + + "github.com/mmcloughlin/avo/ir" +) + +// LabelTarget populates the LabelTarget of the given function. This maps from +// label name to the following instruction. +func LabelTarget(fn *ir.Function) error { + target := map[ir.Label]*ir.Instruction{} + var pending []ir.Label + for _, node := range fn.Nodes { + switch n := node.(type) { + case ir.Label: + if _, found := target[n]; found { + return fmt.Errorf("duplicate label \"%s\"", n) + } + pending = append(pending, n) + case *ir.Instruction: + for _, label := range pending { + target[label] = n + } + pending = nil + } + } + if len(pending) != 0 { + return errors.New("function ends with label") + } + fn.LabelTarget = target + return nil +} + +// CFG constructs the call-flow-graph for the function. +func CFG(fn *ir.Function) error { + is := fn.Instructions() + n := len(is) + + // Populate successors. + for i := 0; i < n; i++ { + cur := is[i] + var nxt *ir.Instruction + if i+1 < n { + nxt = is[i+1] + } + + // If it's a branch, locate the target. + if cur.IsBranch { + lbl := cur.TargetLabel() + if lbl == nil { + return errors.New("no label for branch instruction") + } + target, found := fn.LabelTarget[*lbl] + if !found { + return fmt.Errorf("unknown label %q", *lbl) + } + cur.Succ = append(cur.Succ, target) + } + + // Otherwise, could continue to the following instruction. + switch { + case cur.IsTerminal: + case cur.IsUnconditionalBranch(): + default: + cur.Succ = append(cur.Succ, nxt) + } + } + + // Populate predecessors. + for _, i := range is { + for _, s := range i.Succ { + if s != nil { + s.Pred = append(s.Pred, i) + } + } + } + + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/cleanup.go b/vendor/github.com/mmcloughlin/avo/pass/cleanup.go new file mode 100644 index 0000000..d91250f --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/cleanup.go @@ -0,0 +1,123 @@ +package pass + +import ( + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" +) + +// PruneJumpToFollowingLabel removes jump instructions that target an +// immediately following label. +func PruneJumpToFollowingLabel(fn *ir.Function) error { + for i := 0; i+1 < len(fn.Nodes); i++ { + node := fn.Nodes[i] + next := fn.Nodes[i+1] + + // This node is an unconditional jump. + inst, ok := node.(*ir.Instruction) + if !ok || !inst.IsBranch || inst.IsConditional { + continue + } + + target := inst.TargetLabel() + if target == nil { + continue + } + + // And the jump target is the immediately following node. + lbl, ok := next.(ir.Label) + if !ok || lbl != *target { + continue + } + + // Then the jump is unnecessary and can be removed. + fn.Nodes = deletenode(fn.Nodes, i) + i-- + } + + return nil +} + +// PruneDanglingLabels removes labels that are not referenced by any branches. +func PruneDanglingLabels(fn *ir.Function) error { + // Count label references. + count := map[ir.Label]int{} + for _, n := range fn.Nodes { + i, ok := n.(*ir.Instruction) + if !ok || !i.IsBranch { + continue + } + + target := i.TargetLabel() + if target == nil { + continue + } + + count[*target]++ + } + + // Look for labels with no references. + for i := 0; i < len(fn.Nodes); i++ { + node := fn.Nodes[i] + lbl, ok := node.(ir.Label) + if !ok { + continue + } + + if count[lbl] == 0 { + fn.Nodes = deletenode(fn.Nodes, i) + i-- + } + } + + return nil +} + +// PruneSelfMoves removes move instructions from one register to itself. +func PruneSelfMoves(fn *ir.Function) error { + return removeinstructions(fn, func(i *ir.Instruction) bool { + switch i.Opcode { + case "MOVB", "MOVW", "MOVL", "MOVQ": + default: + return false + } + + return operand.IsRegister(i.Operands[0]) && operand.IsRegister(i.Operands[1]) && i.Operands[0] == i.Operands[1] + }) +} + +// removeinstructions deletes instructions from the given function which match predicate. +func removeinstructions(fn *ir.Function, predicate func(*ir.Instruction) bool) error { + // Removal of instructions has the potential to invalidate CFG structures. + // Clear them to prevent accidental use of stale structures after this pass. + invalidatecfg(fn) + + for i := 0; i < len(fn.Nodes); i++ { + n := fn.Nodes[i] + + inst, ok := n.(*ir.Instruction) + if !ok || !predicate(inst) { + continue + } + + fn.Nodes = deletenode(fn.Nodes, i) + } + + return nil +} + +// deletenode deletes node i from nodes and returns the resulting slice. +func deletenode(nodes []ir.Node, i int) []ir.Node { + n := len(nodes) + copy(nodes[i:], nodes[i+1:]) + nodes[n-1] = nil + return nodes[:n-1] +} + +// invalidatecfg clears CFG structures. +func invalidatecfg(fn *ir.Function) { + fn.LabelTarget = nil + for _, i := range fn.Instructions() { + i.Pred = nil + i.Succ = nil + } +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/isa.go b/vendor/github.com/mmcloughlin/avo/pass/isa.go new file mode 100644 index 0000000..951834d --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/isa.go @@ -0,0 +1,31 @@ +package pass + +import ( + "sort" + + "github.com/mmcloughlin/avo/ir" +) + +// RequiredISAExtensions determines ISA extensions required for the given +// function. Populates the ISA field. +func RequiredISAExtensions(fn *ir.Function) error { + // Collect ISA set. + set := map[string]bool{} + for _, i := range fn.Instructions() { + for _, isa := range i.ISA { + set[isa] = true + } + } + + if len(set) == 0 { + return nil + } + + // Populate the function's ISA field with the unique sorted list. + for isa := range set { + fn.ISA = append(fn.ISA, isa) + } + sort.Strings(fn.ISA) + + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/pass.go b/vendor/github.com/mmcloughlin/avo/pass/pass.go new file mode 100644 index 0000000..62f37b1 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/pass.go @@ -0,0 +1,100 @@ +// Package pass implements processing passes on avo Files. +package pass + +import ( + "io" + + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/printer" +) + +// Compile pass compiles an avo file. Upon successful completion the avo file +// may be printed to Go assembly. +var Compile = Concat( + Verify, + FunctionPass(PruneJumpToFollowingLabel), + FunctionPass(PruneDanglingLabels), + FunctionPass(LabelTarget), + FunctionPass(CFG), + InstructionPass(ZeroExtend32BitOutputs), + FunctionPass(Liveness), + FunctionPass(AllocateRegisters), + FunctionPass(BindRegisters), + FunctionPass(VerifyAllocation), + Func(IncludeTextFlagHeader), + FunctionPass(PruneSelfMoves), + FunctionPass(RequiredISAExtensions), +) + +// Interface for a processing pass. +type Interface interface { + Execute(*ir.File) error +} + +// Func adapts a function to the pass Interface. +type Func func(*ir.File) error + +// Execute calls p. +func (p Func) Execute(f *ir.File) error { + return p(f) +} + +// FunctionPass is a convenience for implementing a full file pass with a +// function that operates on each avo Function independently. +type FunctionPass func(*ir.Function) error + +// Execute calls p on every function in the file. Exits on the first error. +func (p FunctionPass) Execute(f *ir.File) error { + for _, fn := range f.Functions() { + if err := p(fn); err != nil { + return err + } + } + return nil +} + +// InstructionPass is a convenience for implementing a full file pass with a +// function that operates on each Instruction independently. +type InstructionPass func(*ir.Instruction) error + +// Execute calls p on every instruction in the file. Exits on the first error. +func (p InstructionPass) Execute(f *ir.File) error { + for _, fn := range f.Functions() { + for _, i := range fn.Instructions() { + if err := p(i); err != nil { + return err + } + } + } + return nil +} + +// Concat returns a pass that executes the given passes in order, stopping on the first error. +func Concat(passes ...Interface) Interface { + return Func(func(f *ir.File) error { + for _, p := range passes { + if err := p.Execute(f); err != nil { + return err + } + } + return nil + }) +} + +// Output pass prints a file. +type Output struct { + Writer io.WriteCloser + Printer printer.Printer +} + +// Execute prints f with the configured Printer and writes output to Writer. +func (o *Output) Execute(f *ir.File) error { + b, err := o.Printer.Print(f) + if err != nil { + return err + } + if _, err = o.Writer.Write(b); err != nil { + return err + } + return o.Writer.Close() +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/reg.go b/vendor/github.com/mmcloughlin/avo/pass/reg.go new file mode 100644 index 0000000..79147b0 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/reg.go @@ -0,0 +1,139 @@ +package pass + +import ( + "errors" + + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// ZeroExtend32BitOutputs applies the rule that "32-bit operands generate a +// 32-bit result, zero-extended to a 64-bit result in the destination +// general-purpose register" (Intel Software Developer’s Manual, Volume 1, +// 3.4.1.1). +func ZeroExtend32BitOutputs(i *ir.Instruction) error { + for j, op := range i.Outputs { + if !operand.IsR32(op) { + continue + } + r, ok := op.(reg.GP) + if !ok { + panic("r32 operand should satisfy reg.GP") + } + i.Outputs[j] = r.As64() + } + return nil +} + +// Liveness computes register liveness. +func Liveness(fn *ir.Function) error { + // Note this implementation is initially naive so as to be "obviously correct". + // There are a well-known optimizations we can apply if necessary. + + is := fn.Instructions() + + // Process instructions in reverse: poor approximation to topological sort. + // TODO(mbm): process instructions in topological sort order + for l, r := 0, len(is)-1; l < r; l, r = l+1, r-1 { + is[l], is[r] = is[r], is[l] + } + + // Initialize. + for _, i := range is { + i.LiveIn = reg.NewMaskSetFromRegisters(i.InputRegisters()) + i.LiveOut = reg.NewEmptyMaskSet() + } + + // Iterative dataflow analysis. + for { + changes := false + + for _, i := range is { + // out[n] = UNION[s IN succ[n]] in[s] + for _, s := range i.Succ { + if s == nil { + continue + } + changes = i.LiveOut.Update(s.LiveIn) || changes + } + + // in[n] = use[n] UNION (out[n] - def[n]) + def := reg.NewMaskSetFromRegisters(i.OutputRegisters()) + changes = i.LiveIn.Update(i.LiveOut.Difference(def)) || changes + } + + if !changes { + break + } + } + + return nil +} + +// AllocateRegisters performs register allocation. +func AllocateRegisters(fn *ir.Function) error { + // Populate allocators (one per kind). + as := map[reg.Kind]*Allocator{} + for _, i := range fn.Instructions() { + for _, r := range i.Registers() { + k := r.Kind() + if _, found := as[k]; !found { + a, err := NewAllocatorForKind(k) + if err != nil { + return err + } + as[k] = a + } + as[k].Add(r.ID()) + } + } + + // Record register interferences. + for _, i := range fn.Instructions() { + for _, d := range i.OutputRegisters() { + k := d.Kind() + out := i.LiveOut.OfKind(k) + out.DiscardRegister(d) + as[k].AddInterferenceSet(d, out) + } + } + + // Execute register allocation. + fn.Allocation = reg.NewEmptyAllocation() + for _, a := range as { + al, err := a.Allocate() + if err != nil { + return err + } + if err := fn.Allocation.Merge(al); err != nil { + return err + } + } + + return nil +} + +// BindRegisters applies the result of register allocation, replacing all virtual registers with their assigned physical registers. +func BindRegisters(fn *ir.Function) error { + for _, i := range fn.Instructions() { + for idx := range i.Operands { + i.Operands[idx] = operand.ApplyAllocation(i.Operands[idx], fn.Allocation) + } + } + return nil +} + +// VerifyAllocation performs sanity checks following register allocation. +func VerifyAllocation(fn *ir.Function) error { + // All registers should be physical. + for _, i := range fn.Instructions() { + for _, r := range i.Registers() { + if reg.ToPhysical(r) == nil { + return errors.New("non physical register found") + } + } + } + + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/textflag.go b/vendor/github.com/mmcloughlin/avo/pass/textflag.go new file mode 100644 index 0000000..35a848b --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/textflag.go @@ -0,0 +1,42 @@ +package pass + +import ( + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/ir" +) + +// IncludeTextFlagHeader includes textflag.h if necessary. +func IncludeTextFlagHeader(f *ir.File) error { + const textflagheader = "textflag.h" + + // Check if we already have it. + for _, path := range f.Includes { + if path == textflagheader { + return nil + } + } + + // Add it if necessary. + if requirestextflags(f) { + f.Includes = append(f.Includes, textflagheader) + } + + return nil +} + +// requirestextflags returns whether the file uses flags in the textflags.h header. +func requirestextflags(f *ir.File) bool { + for _, s := range f.Sections { + var a attr.Attribute + switch s := s.(type) { + case *ir.Function: + a = s.Attributes + case *ir.Global: + a = s.Attributes + } + if a.ContainsTextFlags() { + return true + } + } + return false +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/verify.go b/vendor/github.com/mmcloughlin/avo/pass/verify.go new file mode 100644 index 0000000..1e7b368 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/verify.go @@ -0,0 +1,32 @@ +package pass + +import ( + "errors" + + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" +) + +// Verify pass validates an avo file. +var Verify = Concat( + InstructionPass(VerifyMemOperands), +) + +// VerifyMemOperands checks the instruction's memory operands. +func VerifyMemOperands(i *ir.Instruction) error { + for _, op := range i.Operands { + m, ok := op.(operand.Mem) + if !ok { + continue + } + + if m.Base == nil { + return errors.New("bad memory operand: missing base register") + } + + if m.Index != nil && m.Scale == 0 { + return errors.New("bad memory operand: index register with scale 0") + } + } + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/goasm.go b/vendor/github.com/mmcloughlin/avo/printer/goasm.go new file mode 100644 index 0000000..0d8a12c --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/goasm.go @@ -0,0 +1,186 @@ +package printer + +import ( + "strconv" + "strings" + + "github.com/mmcloughlin/avo/internal/prnt" + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" +) + +// dot is the pesky unicode dot used in Go assembly. +const dot = "\u00b7" + +type goasm struct { + cfg Config + prnt.Generator + + instructions []*ir.Instruction + clear bool +} + +// NewGoAsm constructs a printer for writing Go assembly files. +func NewGoAsm(cfg Config) Printer { + return &goasm{cfg: cfg} +} + +func (p *goasm) Print(f *ir.File) ([]byte, error) { + p.header(f) + for _, s := range f.Sections { + switch s := s.(type) { + case *ir.Function: + p.function(s) + case *ir.Global: + p.global(s) + default: + panic("unknown section type") + } + } + return p.Result() +} + +func (p *goasm) header(f *ir.File) { + p.Comment(p.cfg.GeneratedWarning()) + + if len(f.Constraints) > 0 { + p.NL() + p.Printf(f.Constraints.GoString()) + } + + if len(f.Includes) > 0 { + p.NL() + p.includes(f.Includes) + } +} + +func (p *goasm) includes(paths []string) { + for _, path := range paths { + p.Printf("#include \"%s\"\n", path) + } +} + +func (p *goasm) function(f *ir.Function) { + p.NL() + p.Comment(f.Stub()) + + if len(f.ISA) > 0 { + p.Comment("Requires: " + strings.Join(f.ISA, ", ")) + } + + // Reference: https://github.com/golang/go/blob/b115207baf6c2decc3820ada4574ef4e5ad940ec/src/cmd/internal/obj/util.go#L166-L176 + // + // if p.As == ATEXT { + // // If there are attributes, print them. Otherwise, skip the comma. + // // In short, print one of these two: + // // TEXT foo(SB), DUPOK|NOSPLIT, $0 + // // TEXT foo(SB), $0 + // s := p.From.Sym.Attribute.TextAttrString() + // if s != "" { + // fmt.Fprintf(&buf, "%s%s", sep, s) + // sep = ", " + // } + // } + // + p.Printf("TEXT %s%s(SB)", dot, f.Name) + if f.Attributes != 0 { + p.Printf(", %s", f.Attributes.Asm()) + } + p.Printf(", %s\n", textsize(f)) + + p.clear = true + for _, node := range f.Nodes { + switch n := node.(type) { + case *ir.Instruction: + p.instruction(n) + if n.IsTerminal || n.IsUnconditionalBranch() { + p.flush() + } + case ir.Label: + p.flush() + p.ensureclear() + p.Printf("%s:\n", n) + case *ir.Comment: + p.flush() + p.ensureclear() + for _, line := range n.Lines { + p.Printf("\t// %s\n", line) + } + default: + panic("unexpected node type") + } + } + p.flush() +} + +func (p *goasm) instruction(i *ir.Instruction) { + p.instructions = append(p.instructions, i) + p.clear = false +} + +func (p *goasm) flush() { + if len(p.instructions) == 0 { + return + } + + // Determine instruction width. Instructions with no operands are not + // considered in this calculation. + width := 0 + for _, i := range p.instructions { + if len(i.Operands) > 0 && len(i.Opcode) > width { + width = len(i.Opcode) + } + } + + // Output instruction block. + for _, i := range p.instructions { + if len(i.Operands) > 0 { + p.Printf("\t%-*s%s\n", width+1, i.Opcode, joinOperands(i.Operands)) + } else { + p.Printf("\t%s\n", i.Opcode) + } + } + + p.instructions = nil +} + +func (p *goasm) ensureclear() { + if !p.clear { + p.NL() + p.clear = true + } +} + +func (p *goasm) global(g *ir.Global) { + p.NL() + for _, d := range g.Data { + a := operand.NewDataAddr(g.Symbol, d.Offset) + p.Printf("DATA %s/%d, %s\n", a.Asm(), d.Value.Bytes(), d.Value.Asm()) + } + p.Printf("GLOBL %s(SB), %s, $%d\n", g.Symbol, g.Attributes.Asm(), g.Size) +} + +func textsize(f *ir.Function) string { + // Reference: https://github.com/golang/go/blob/b115207baf6c2decc3820ada4574ef4e5ad940ec/src/cmd/internal/obj/util.go#L260-L265 + // + // case TYPE_TEXTSIZE: + // if a.Val.(int32) == objabi.ArgsSizeUnknown { + // str = fmt.Sprintf("$%d", a.Offset) + // } else { + // str = fmt.Sprintf("$%d-%d", a.Offset, a.Val.(int32)) + // } + // + s := "$" + strconv.Itoa(f.FrameBytes()) + if argsize := f.ArgumentBytes(); argsize > 0 { + return s + "-" + strconv.Itoa(argsize) + } + return s +} + +func joinOperands(operands []operand.Op) string { + asm := make([]string, len(operands)) + for i, op := range operands { + asm[i] = op.Asm() + } + return strings.Join(asm, ", ") +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/printer.go b/vendor/github.com/mmcloughlin/avo/printer/printer.go new file mode 100644 index 0000000..b562c74 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/printer.go @@ -0,0 +1,98 @@ +// Package printer implements printing of avo files in various formats. +package printer + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/mmcloughlin/avo/internal/stack" + "github.com/mmcloughlin/avo/ir" +) + +// Printer can produce output for an avo File. +type Printer interface { + Print(*ir.File) ([]byte, error) +} + +// Builder can construct a printer. +type Builder func(Config) Printer + +// Config represents general printing configuration. +type Config struct { + // Command-line arguments passed to the generator. If provided, this will be + // included in a code generation warning. + Argv []string + + // Name of the code generator. + Name string + + // Name of Go package the generated code will belong to. + Pkg string +} + +// NewDefaultConfig produces a config with Name "avo". +// The package name is guessed from the current directory. +func NewDefaultConfig() Config { + return Config{ + Name: "avo", + Pkg: pkg(), + } +} + +// NewArgvConfig constructs a Config from os.Args. +// The package name is guessed from the current directory. +func NewArgvConfig() Config { + return Config{ + Argv: os.Args, + Pkg: pkg(), + } +} + +// NewGoRunConfig produces a Config for a generator that's expected to be +// executed via "go run ...". +func NewGoRunConfig() Config { + path := mainfile() + if path == "" { + return NewDefaultConfig() + } + argv := []string{"go", "run", filepath.Base(path)} + if len(os.Args) > 1 { + argv = append(argv, os.Args[1:]...) + } + return Config{ + Argv: argv, + Pkg: pkg(), + } +} + +// GeneratedBy returns a description of the code generator. +func (c Config) GeneratedBy() string { + if c.Argv == nil { + return c.Name + } + return fmt.Sprintf("command: %s", strings.Join(c.Argv, " ")) +} + +// GeneratedWarning returns text for a code generation warning. Conforms to https://golang.org/s/generatedcode. +func (c Config) GeneratedWarning() string { + return fmt.Sprintf("Code generated by %s. DO NOT EDIT.", c.GeneratedBy()) +} + +// mainfile attempts to determine the file path of the main function by +// inspecting the stack. Returns empty string on failure. +func mainfile() string { + if m := stack.Main(); m != nil { + return m.File + } + return "" +} + +// pkg guesses the name of the package from the working directory. +func pkg() string { + if cwd, err := os.Getwd(); err == nil { + return filepath.Base(cwd) + } + return "" +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/stubs.go b/vendor/github.com/mmcloughlin/avo/printer/stubs.go new file mode 100644 index 0000000..171bc62 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/stubs.go @@ -0,0 +1,45 @@ +package printer + +import ( + "github.com/mmcloughlin/avo/internal/prnt" + "github.com/mmcloughlin/avo/ir" +) + +type stubs struct { + cfg Config + prnt.Generator +} + +// NewStubs constructs a printer for writing stub function declarations. +func NewStubs(cfg Config) Printer { + return &stubs{cfg: cfg} +} + +func (s *stubs) Print(f *ir.File) ([]byte, error) { + s.Comment(s.cfg.GeneratedWarning()) + + if len(f.Constraints) > 0 { + s.NL() + s.Printf(f.Constraints.GoString()) + } + + s.NL() + s.Printf("package %s\n", s.cfg.Pkg) + for _, fn := range f.Functions() { + s.NL() + s.Comment(fn.Doc...) + for _, pragma := range fn.Pragmas { + s.pragma(pragma) + } + s.Printf("%s\n", fn.Stub()) + } + return s.Result() +} + +func (s *stubs) pragma(p ir.Pragma) { + s.Printf("//go:%s", p.Directive) + for _, arg := range p.Arguments { + s.Printf(" %s", arg) + } + s.NL() +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/collection.go b/vendor/github.com/mmcloughlin/avo/reg/collection.go new file mode 100644 index 0000000..d35c3a0 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/collection.go @@ -0,0 +1,54 @@ +package reg + +// Collection represents a collection of virtual registers. This is primarily +// useful for allocating virtual registers with distinct IDs. +type Collection struct { + idx map[Kind]Index +} + +// NewCollection builds an empty register collection. +func NewCollection() *Collection { + return &Collection{ + idx: map[Kind]Index{}, + } +} + +// VirtualRegister allocates and returns a new virtual register of the given kind and width. +func (c *Collection) VirtualRegister(k Kind, s Spec) Virtual { + idx := c.idx[k] + c.idx[k]++ + return NewVirtual(idx, k, s) +} + +// GP8L allocates and returns a general-purpose 8-bit register (low byte). +func (c *Collection) GP8L() GPVirtual { return c.GP(S8L) } + +// GP8H allocates and returns a general-purpose 8-bit register (high byte). +func (c *Collection) GP8H() GPVirtual { return c.GP(S8H) } + +// GP8 allocates and returns a general-purpose 8-bit register (low byte). +func (c *Collection) GP8() GPVirtual { return c.GP8L() } + +// GP16 allocates and returns a general-purpose 16-bit register. +func (c *Collection) GP16() GPVirtual { return c.GP(S16) } + +// GP32 allocates and returns a general-purpose 32-bit register. +func (c *Collection) GP32() GPVirtual { return c.GP(S32) } + +// GP64 allocates and returns a general-purpose 64-bit register. +func (c *Collection) GP64() GPVirtual { return c.GP(S64) } + +// GP allocates and returns a general-purpose register of the given width. +func (c *Collection) GP(s Spec) GPVirtual { return newgpv(c.VirtualRegister(KindGP, s)) } + +// XMM allocates and returns a 128-bit vector register. +func (c *Collection) XMM() VecVirtual { return c.Vec(S128) } + +// YMM allocates and returns a 256-bit vector register. +func (c *Collection) YMM() VecVirtual { return c.Vec(S256) } + +// ZMM allocates and returns a 512-bit vector register. +func (c *Collection) ZMM() VecVirtual { return c.Vec(S512) } + +// Vec allocates and returns a vector register of the given width. +func (c *Collection) Vec(s Spec) VecVirtual { return newvecv(c.VirtualRegister(KindVector, s)) } diff --git a/vendor/github.com/mmcloughlin/avo/reg/doc.go b/vendor/github.com/mmcloughlin/avo/reg/doc.go new file mode 100644 index 0000000..1c0aee3 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/doc.go @@ -0,0 +1,2 @@ +// Package reg provides types for physical and virtual registers, and definitions of x86-64 register families. +package reg diff --git a/vendor/github.com/mmcloughlin/avo/reg/set.go b/vendor/github.com/mmcloughlin/avo/reg/set.go new file mode 100644 index 0000000..2cf8814 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/set.go @@ -0,0 +1,112 @@ +package reg + +// MaskSet maps register IDs to masks. +type MaskSet map[ID]uint16 + +// NewEmptyMaskSet builds an empty register mask set. +func NewEmptyMaskSet() MaskSet { + return MaskSet{} +} + +// NewMaskSetFromRegisters forms a mask set from the given register list. +func NewMaskSetFromRegisters(rs []Register) MaskSet { + s := NewEmptyMaskSet() + for _, r := range rs { + s.AddRegister(r) + } + return s +} + +// Clone returns a copy of s. +func (s MaskSet) Clone() MaskSet { + c := NewEmptyMaskSet() + for id, mask := range s { + c.Add(id, mask) + } + return c +} + +// Add mask to the given register ID. +// Reports whether this made any change to the set. +func (s MaskSet) Add(id ID, mask uint16) bool { + if (s[id] & mask) == mask { + return false + } + s[id] |= mask + return true +} + +// AddRegister is a convenience for adding the register's (ID, mask) to the set. +// Reports whether this made any change to the set. +func (s MaskSet) AddRegister(r Register) bool { + return s.Add(r.ID(), r.Mask()) +} + +// Discard clears masked bits from register ID. +// Reports whether this made any change to the set. +func (s MaskSet) Discard(id ID, mask uint16) bool { + if curr, found := s[id]; !found || (curr&mask) == 0 { + return false + } + s[id] &^= mask + if s[id] == 0 { + delete(s, id) + } + return true +} + +// DiscardRegister is a convenience for discarding the register's (ID, mask) from the set. +// Reports whether this made any change to the set. +func (s MaskSet) DiscardRegister(r Register) bool { + return s.Discard(r.ID(), r.Mask()) +} + +// Update adds masks in t to s. +// Reports whether this made any change to the set. +func (s MaskSet) Update(t MaskSet) bool { + change := false + for id, mask := range t { + change = s.Add(id, mask) || change + } + return change +} + +// Difference returns the set of registers in s but not t. +func (s MaskSet) Difference(t MaskSet) MaskSet { + d := s.Clone() + d.DifferenceUpdate(t) + return d +} + +// DifferenceUpdate removes every element of t from s. +func (s MaskSet) DifferenceUpdate(t MaskSet) bool { + change := false + for id, mask := range t { + change = s.Discard(id, mask) || change + } + return change +} + +// Equals returns true if s and t contain the same masks. +func (s MaskSet) Equals(t MaskSet) bool { + if len(s) != len(t) { + return false + } + for id, mask := range s { + if _, found := t[id]; !found || mask != t[id] { + return false + } + } + return true +} + +// OfKind returns the set of elements of s with kind k. +func (s MaskSet) OfKind(k Kind) MaskSet { + t := NewEmptyMaskSet() + for id, mask := range s { + if id.Kind() == k { + t.Add(id, mask) + } + } + return t +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/types.go b/vendor/github.com/mmcloughlin/avo/reg/types.go new file mode 100644 index 0000000..9f69e91 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/types.go @@ -0,0 +1,304 @@ +package reg + +import ( + "errors" + "fmt" +) + +// Kind is a class of registers. +type Kind uint8 + +// Index of a register within a kind. +type Index uint16 + +// Family is a collection of Physical registers of a common kind. +type Family struct { + Kind Kind + registers []Physical +} + +// define builds a register and adds it to the Family. +func (f *Family) define(s Spec, idx Index, name string, flags ...Info) Physical { + r := newregister(f, s, idx, name, flags...) + f.add(r) + return r +} + +// add r to the family. +func (f *Family) add(r Physical) { + if r.Kind() != f.Kind { + panic("bad kind") + } + f.registers = append(f.registers, r) +} + +// Virtual returns a virtual register from this family's kind. +func (f *Family) Virtual(idx Index, s Spec) Virtual { + return NewVirtual(idx, f.Kind, s) +} + +// Registers returns the registers in this family. +func (f *Family) Registers() []Physical { + return append([]Physical(nil), f.registers...) +} + +// Lookup returns the register with given physical index and spec. Returns nil if no such register exists. +func (f *Family) Lookup(idx Index, s Spec) Physical { + for _, r := range f.registers { + if r.PhysicalIndex() == idx && r.Mask() == s.Mask() { + return r + } + } + return nil +} + +// ID is a register identifier. +type ID uint32 + +// newid builds a new register ID from the virtual flag v, kind and index. +func newid(v uint8, kind Kind, idx Index) ID { + return ID(v) | (ID(kind) << 8) | (ID(idx) << 16) +} + +// IsVirtual reports whether this is an ID for a virtual register. +func (id ID) IsVirtual() bool { return (id & 1) == 1 } + +// IsPhysical reports whether this is an ID for a physical register. +func (id ID) IsPhysical() bool { return !id.IsVirtual() } + +// Kind extracts the kind from the register ID. +func (id ID) Kind() Kind { return Kind(id >> 8) } + +// Index extracts the index from the register ID. +func (id ID) Index() Index { return Index(id >> 16) } + +// Register represents a virtual or physical register. +type Register interface { + ID() ID + Kind() Kind + Size() uint + Mask() uint16 + Asm() string + as(Spec) Register + spec() Spec + register() +} + +// Equal reports whether a and b are equal registers. +func Equal(a, b Register) bool { + return (a.ID() == b.ID()) && (a.Mask() == b.Mask()) +} + +// Virtual is a register of a given type and size, not yet allocated to a physical register. +type Virtual interface { + VirtualIndex() Index + Register +} + +// ToVirtual converts r to Virtual if possible, otherwise returns nil. +func ToVirtual(r Register) Virtual { + if v, ok := r.(Virtual); ok { + return v + } + return nil +} + +type virtual struct { + idx Index + kind Kind + Spec +} + +// NewVirtual builds a Virtual register. +func NewVirtual(idx Index, k Kind, s Spec) Virtual { + return virtual{ + idx: idx, + kind: k, + Spec: s, + } +} + +func (v virtual) ID() ID { return newid(1, v.kind, v.idx) } +func (v virtual) VirtualIndex() Index { return v.idx } +func (v virtual) Kind() Kind { return v.kind } + +func (v virtual) Asm() string { + // TODO(mbm): decide on virtual register syntax + return fmt.Sprintf("<virtual:%v:%v:%v>", v.idx, v.Kind(), v.Size()) +} + +func (v virtual) as(s Spec) Register { + return virtual{ + idx: v.idx, + kind: v.kind, + Spec: s, + } +} + +func (v virtual) spec() Spec { return v.Spec } +func (v virtual) register() {} + +// Info is a bitmask of register properties. +type Info uint8 + +// Defined register Info flags. +const ( + None Info = 0 + Restricted Info = 1 << iota +) + +// Physical is a concrete register. +type Physical interface { + PhysicalIndex() Index + Info() Info + Register +} + +// ToPhysical converts r to Physical if possible, otherwise returns nil. +func ToPhysical(r Register) Physical { + if p, ok := r.(Physical); ok { + return p + } + return nil +} + +// register implements Physical. +type register struct { + family *Family + idx Index + name string + info Info + Spec +} + +func newregister(f *Family, s Spec, idx Index, name string, flags ...Info) register { + r := register{ + family: f, + idx: idx, + name: name, + info: None, + Spec: s, + } + for _, flag := range flags { + r.info |= flag + } + return r +} + +func (r register) ID() ID { return newid(0, r.Kind(), r.idx) } +func (r register) PhysicalIndex() Index { return r.idx } +func (r register) Kind() Kind { return r.family.Kind } +func (r register) Asm() string { return r.name } +func (r register) Info() Info { return r.info } + +func (r register) as(s Spec) Register { + return r.family.Lookup(r.PhysicalIndex(), s) +} + +func (r register) spec() Spec { return r.Spec } +func (r register) register() {} + +// Spec defines the size of a register as well as the bit ranges it occupies in +// an underlying physical register. +type Spec uint16 + +// Spec values required for x86-64. +const ( + S0 Spec = 0x0 // zero value reserved for pseudo registers + S8L Spec = 0x1 + S8H Spec = 0x2 + S8 = S8L + S16 Spec = 0x3 + S32 Spec = 0x7 + S64 Spec = 0xf + S128 Spec = 0x1f + S256 Spec = 0x3f + S512 Spec = 0x7f +) + +// Mask returns a mask representing which bytes of an underlying register are +// used by this register. This is almost always the low bytes, except for the +// case of the high-byte registers. If bit n of the mask is set, this means +// bytes 2^(n-1) to 2^n-1 are used. +func (s Spec) Mask() uint16 { + return uint16(s) +} + +// Size returns the register width in bytes. +func (s Spec) Size() uint { + x := uint(s) + return (x >> 1) + (x & 1) +} + +// LookupPhysical returns the physical register with the given parameters, or nil if not found. +func LookupPhysical(k Kind, idx Index, s Spec) Physical { + f := FamilyOfKind(k) + if f == nil { + return nil + } + return f.Lookup(idx, s) +} + +// LookupID returns the physical register with the given id and spec, or nil if not found. +func LookupID(id ID, s Spec) Physical { + if id.IsVirtual() { + return nil + } + return LookupPhysical(id.Kind(), id.Index(), s) +} + +// Allocation records a register allocation. +type Allocation map[ID]ID + +// NewEmptyAllocation builds an empty register allocation. +func NewEmptyAllocation() Allocation { + return Allocation{} +} + +// Merge allocations from b into a. Errors if there is disagreement on a common +// register. +func (a Allocation) Merge(b Allocation) error { + for id, p := range b { + if alt, found := a[id]; found && alt != p { + return errors.New("disagreement on overlapping register") + } + a[id] = p + } + return nil +} + +// LookupDefault returns the register ID assigned by this allocation, returning +// id if none is found. +func (a Allocation) LookupDefault(id ID) ID { + if _, found := a[id]; found { + return a[id] + } + return id +} + +// LookupRegister the allocation for register r, or return nil if there is none. +func (a Allocation) LookupRegister(r Register) Physical { + // Return immediately if it is already a physical register. + if p := ToPhysical(r); p != nil { + return p + } + + // Lookup an allocation for this virtual ID. + id, found := a[r.ID()] + if !found { + return nil + } + + return LookupID(id, r.spec()) +} + +// LookupRegisterDefault returns the register assigned to r, or r itself if there is none. +func (a Allocation) LookupRegisterDefault(r Register) Register { + if r == nil { + return nil + } + if p := a.LookupRegister(r); p != nil { + return p + } + return r +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/x86.go b/vendor/github.com/mmcloughlin/avo/reg/x86.go new file mode 100644 index 0000000..a1ec94c --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/x86.go @@ -0,0 +1,331 @@ +package reg + +// Register kinds. +const ( + KindPseudo Kind = iota + KindGP + KindVector +) + +// Declare register families. +var ( + Pseudo = &Family{Kind: KindPseudo} + GeneralPurpose = &Family{Kind: KindGP} + Vector = &Family{Kind: KindVector} + + Families = []*Family{ + Pseudo, + GeneralPurpose, + Vector, + } +) + +var familiesByKind = map[Kind]*Family{} + +func init() { + for _, f := range Families { + familiesByKind[f.Kind] = f + } +} + +// FamilyOfKind returns the Family of registers of the given kind, or nil if not found. +func FamilyOfKind(k Kind) *Family { + return familiesByKind[k] +} + +// Pseudo registers. +var ( + FramePointer = Pseudo.define(S0, 0, "FP") + ProgramCounter = Pseudo.define(S0, 0, "PC") + StaticBase = Pseudo.define(S0, 0, "SB") + StackPointer = Pseudo.define(S0, 0, "SP") +) + +// GP provides additional methods for general purpose registers. +type GP interface { + As8() Register + As8L() Register + As8H() Register + As16() Register + As32() Register + As64() Register +} + +// GPPhysical is a general-purpose physical register. +type GPPhysical interface { + Physical + GP +} + +type gpp struct { + Physical +} + +func newgpp(r Physical) GPPhysical { return gpp{Physical: r} } + +func (p gpp) As8() Register { return newgpp(p.as(S8).(Physical)) } +func (p gpp) As8L() Register { return newgpp(p.as(S8L).(Physical)) } +func (p gpp) As8H() Register { return newgpp(p.as(S8H).(Physical)) } +func (p gpp) As16() Register { return newgpp(p.as(S16).(Physical)) } +func (p gpp) As32() Register { return newgpp(p.as(S32).(Physical)) } +func (p gpp) As64() Register { return newgpp(p.as(S64).(Physical)) } + +// GPVirtual is a general-purpose virtual register. +type GPVirtual interface { + Virtual + GP +} + +type gpv struct { + Virtual +} + +func newgpv(v Virtual) GPVirtual { return gpv{Virtual: v} } + +func (v gpv) As8() Register { return newgpv(v.as(S8).(Virtual)) } +func (v gpv) As8L() Register { return newgpv(v.as(S8L).(Virtual)) } +func (v gpv) As8H() Register { return newgpv(v.as(S8H).(Virtual)) } +func (v gpv) As16() Register { return newgpv(v.as(S16).(Virtual)) } +func (v gpv) As32() Register { return newgpv(v.as(S32).(Virtual)) } +func (v gpv) As64() Register { return newgpv(v.as(S64).(Virtual)) } + +func gp(s Spec, id Index, name string, flags ...Info) GPPhysical { + r := newgpp(newregister(GeneralPurpose, s, id, name, flags...)) + GeneralPurpose.add(r) + return r +} + +// General purpose registers. +var ( + // Low byte + AL = gp(S8L, 0, "AL") + CL = gp(S8L, 1, "CL") + DL = gp(S8L, 2, "DL") + BL = gp(S8L, 3, "BL") + + // High byte + AH = gp(S8H, 0, "AH") + CH = gp(S8H, 1, "CH") + DH = gp(S8H, 2, "DH") + BH = gp(S8H, 3, "BH") + + // 8-bit + SPB = gp(S8, 4, "SP", Restricted) + BPB = gp(S8, 5, "BP") + SIB = gp(S8, 6, "SI") + DIB = gp(S8, 7, "DI") + R8B = gp(S8, 8, "R8") + R9B = gp(S8, 9, "R9") + R10B = gp(S8, 10, "R10") + R11B = gp(S8, 11, "R11") + R12B = gp(S8, 12, "R12") + R13B = gp(S8, 13, "R13") + R14B = gp(S8, 14, "R14") + R15B = gp(S8, 15, "R15") + + // 16-bit + AX = gp(S16, 0, "AX") + CX = gp(S16, 1, "CX") + DX = gp(S16, 2, "DX") + BX = gp(S16, 3, "BX") + SP = gp(S16, 4, "SP", Restricted) + BP = gp(S16, 5, "BP") + SI = gp(S16, 6, "SI") + DI = gp(S16, 7, "DI") + R8W = gp(S16, 8, "R8") + R9W = gp(S16, 9, "R9") + R10W = gp(S16, 10, "R10") + R11W = gp(S16, 11, "R11") + R12W = gp(S16, 12, "R12") + R13W = gp(S16, 13, "R13") + R14W = gp(S16, 14, "R14") + R15W = gp(S16, 15, "R15") + + // 32-bit + EAX = gp(S32, 0, "AX") + ECX = gp(S32, 1, "CX") + EDX = gp(S32, 2, "DX") + EBX = gp(S32, 3, "BX") + ESP = gp(S32, 4, "SP", Restricted) + EBP = gp(S32, 5, "BP") + ESI = gp(S32, 6, "SI") + EDI = gp(S32, 7, "DI") + R8L = gp(S32, 8, "R8") + R9L = gp(S32, 9, "R9") + R10L = gp(S32, 10, "R10") + R11L = gp(S32, 11, "R11") + R12L = gp(S32, 12, "R12") + R13L = gp(S32, 13, "R13") + R14L = gp(S32, 14, "R14") + R15L = gp(S32, 15, "R15") + + // 64-bit + RAX = gp(S64, 0, "AX") + RCX = gp(S64, 1, "CX") + RDX = gp(S64, 2, "DX") + RBX = gp(S64, 3, "BX") + RSP = gp(S64, 4, "SP", Restricted) + RBP = gp(S64, 5, "BP") + RSI = gp(S64, 6, "SI") + RDI = gp(S64, 7, "DI") + R8 = gp(S64, 8, "R8") + R9 = gp(S64, 9, "R9") + R10 = gp(S64, 10, "R10") + R11 = gp(S64, 11, "R11") + R12 = gp(S64, 12, "R12") + R13 = gp(S64, 13, "R13") + R14 = gp(S64, 14, "R14") + R15 = gp(S64, 15, "R15") +) + +// Vec provides methods for vector registers. +type Vec interface { + AsX() Register + AsY() Register + AsZ() Register +} + +// VecPhysical is a physical vector register. +type VecPhysical interface { + Physical + Vec +} + +type vecp struct { + Physical + Vec +} + +func newvecp(r Physical) VecPhysical { return vecp{Physical: r} } + +func (p vecp) AsX() Register { return newvecp(p.as(S128).(Physical)) } +func (p vecp) AsY() Register { return newvecp(p.as(S256).(Physical)) } +func (p vecp) AsZ() Register { return newvecp(p.as(S512).(Physical)) } + +// VecVirtual is a virtual vector register. +type VecVirtual interface { + Virtual + Vec +} + +type vecv struct { + Virtual + Vec +} + +func newvecv(v Virtual) VecVirtual { return vecv{Virtual: v} } + +func (v vecv) AsX() Register { return newvecv(v.as(S128).(Virtual)) } +func (v vecv) AsY() Register { return newvecv(v.as(S256).(Virtual)) } +func (v vecv) AsZ() Register { return newvecv(v.as(S512).(Virtual)) } + +func vec(s Spec, id Index, name string, flags ...Info) VecPhysical { + r := newvecp(newregister(Vector, s, id, name, flags...)) + Vector.add(r) + return r +} + +// Vector registers. +var ( + // 128-bit + X0 = vec(S128, 0, "X0") + X1 = vec(S128, 1, "X1") + X2 = vec(S128, 2, "X2") + X3 = vec(S128, 3, "X3") + X4 = vec(S128, 4, "X4") + X5 = vec(S128, 5, "X5") + X6 = vec(S128, 6, "X6") + X7 = vec(S128, 7, "X7") + X8 = vec(S128, 8, "X8") + X9 = vec(S128, 9, "X9") + X10 = vec(S128, 10, "X10") + X11 = vec(S128, 11, "X11") + X12 = vec(S128, 12, "X12") + X13 = vec(S128, 13, "X13") + X14 = vec(S128, 14, "X14") + X15 = vec(S128, 15, "X15") + X16 = vec(S128, 16, "X16") + X17 = vec(S128, 17, "X17") + X18 = vec(S128, 18, "X18") + X19 = vec(S128, 19, "X19") + X20 = vec(S128, 20, "X20") + X21 = vec(S128, 21, "X21") + X22 = vec(S128, 22, "X22") + X23 = vec(S128, 23, "X23") + X24 = vec(S128, 24, "X24") + X25 = vec(S128, 25, "X25") + X26 = vec(S128, 26, "X26") + X27 = vec(S128, 27, "X27") + X28 = vec(S128, 28, "X28") + X29 = vec(S128, 29, "X29") + X30 = vec(S128, 30, "X30") + X31 = vec(S128, 31, "X31") + + // 256-bit + Y0 = vec(S256, 0, "Y0") + Y1 = vec(S256, 1, "Y1") + Y2 = vec(S256, 2, "Y2") + Y3 = vec(S256, 3, "Y3") + Y4 = vec(S256, 4, "Y4") + Y5 = vec(S256, 5, "Y5") + Y6 = vec(S256, 6, "Y6") + Y7 = vec(S256, 7, "Y7") + Y8 = vec(S256, 8, "Y8") + Y9 = vec(S256, 9, "Y9") + Y10 = vec(S256, 10, "Y10") + Y11 = vec(S256, 11, "Y11") + Y12 = vec(S256, 12, "Y12") + Y13 = vec(S256, 13, "Y13") + Y14 = vec(S256, 14, "Y14") + Y15 = vec(S256, 15, "Y15") + Y16 = vec(S256, 16, "Y16") + Y17 = vec(S256, 17, "Y17") + Y18 = vec(S256, 18, "Y18") + Y19 = vec(S256, 19, "Y19") + Y20 = vec(S256, 20, "Y20") + Y21 = vec(S256, 21, "Y21") + Y22 = vec(S256, 22, "Y22") + Y23 = vec(S256, 23, "Y23") + Y24 = vec(S256, 24, "Y24") + Y25 = vec(S256, 25, "Y25") + Y26 = vec(S256, 26, "Y26") + Y27 = vec(S256, 27, "Y27") + Y28 = vec(S256, 28, "Y28") + Y29 = vec(S256, 29, "Y29") + Y30 = vec(S256, 30, "Y30") + Y31 = vec(S256, 31, "Y31") + + // 512-bit + Z0 = vec(S512, 0, "Z0") + Z1 = vec(S512, 1, "Z1") + Z2 = vec(S512, 2, "Z2") + Z3 = vec(S512, 3, "Z3") + Z4 = vec(S512, 4, "Z4") + Z5 = vec(S512, 5, "Z5") + Z6 = vec(S512, 6, "Z6") + Z7 = vec(S512, 7, "Z7") + Z8 = vec(S512, 8, "Z8") + Z9 = vec(S512, 9, "Z9") + Z10 = vec(S512, 10, "Z10") + Z11 = vec(S512, 11, "Z11") + Z12 = vec(S512, 12, "Z12") + Z13 = vec(S512, 13, "Z13") + Z14 = vec(S512, 14, "Z14") + Z15 = vec(S512, 15, "Z15") + Z16 = vec(S512, 16, "Z16") + Z17 = vec(S512, 17, "Z17") + Z18 = vec(S512, 18, "Z18") + Z19 = vec(S512, 19, "Z19") + Z20 = vec(S512, 20, "Z20") + Z21 = vec(S512, 21, "Z21") + Z22 = vec(S512, 22, "Z22") + Z23 = vec(S512, 23, "Z23") + Z24 = vec(S512, 24, "Z24") + Z25 = vec(S512, 25, "Z25") + Z26 = vec(S512, 26, "Z26") + Z27 = vec(S512, 27, "Z27") + Z28 = vec(S512, 28, "Z28") + Z29 = vec(S512, 29, "Z29") + Z30 = vec(S512, 30, "Z30") + Z31 = vec(S512, 31, "Z31") +) diff --git a/vendor/github.com/mmcloughlin/avo/src/src.go b/vendor/github.com/mmcloughlin/avo/src/src.go new file mode 100644 index 0000000..3a47886 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/src/src.go @@ -0,0 +1,62 @@ +// Package src provides types for working with source files. +package src + +import ( + "os" + "path/filepath" + "runtime" + "strconv" +) + +// Position represents a position in a source file. +type Position struct { + Filename string + Line int // 1-up +} + +// FramePosition returns the Position of the given stack frame. +func FramePosition(f runtime.Frame) Position { + return Position{ + Filename: f.File, + Line: f.Line, + } +} + +// IsValid reports whether the position is valid: Line must be positive, but +// Filename may be empty. +func (p Position) IsValid() bool { + return p.Line > 0 +} + +// String represents Position as a string. +func (p Position) String() string { + if !p.IsValid() { + return "-" + } + var s string + if p.Filename != "" { + s += p.Filename + ":" + } + s += strconv.Itoa(p.Line) + return s +} + +// Rel returns Position relative to basepath. If the given filename cannot be +// expressed relative to basepath the position will be returned unchanged. +func (p Position) Rel(basepath string) Position { + q := p + if rel, err := filepath.Rel(basepath, q.Filename); err == nil { + q.Filename = rel + } + return q +} + +// Relwd returns Position relative to the current working directory. Returns p +// unchanged if the working directory cannot be determined, or the filename +// cannot be expressed relative to the working directory. +func (p Position) Relwd() Position { + if wd, err := os.Getwd(); err == nil { + return p.Rel(wd) + } + return p +} diff --git a/vendor/github.com/mmcloughlin/avo/x86/doc.go b/vendor/github.com/mmcloughlin/avo/x86/doc.go new file mode 100644 index 0000000..6e4c8ee --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/doc.go @@ -0,0 +1,2 @@ +// Package x86 provides constructors for all x86-64 instructions. +package x86 diff --git a/vendor/github.com/mmcloughlin/avo/x86/gen.go b/vendor/github.com/mmcloughlin/avo/x86/gen.go new file mode 100644 index 0000000..25d15fa --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/gen.go @@ -0,0 +1,4 @@ +package x86 + +//go:generate avogen -output zctors.go ctors +//go:generate avogen -output zctors_test.go ctorstest diff --git a/vendor/github.com/mmcloughlin/avo/x86/zctors.go b/vendor/github.com/mmcloughlin/avo/x86/zctors.go new file mode 100644 index 0000000..447c0a1 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/zctors.go @@ -0,0 +1,34629 @@ +// Code generated by command: avogen -output zctors.go ctors. DO NOT EDIT. + +package x86 + +import ( + "errors" + + intrep "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +func ADCB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADCB: bad operands") +} + +// ADCL: Add with Carry. +// +// Forms: +// +// ADCL imm32 eax +// ADCL imm8 r32 +// ADCL imm32 r32 +// ADCL r32 r32 +// ADCL m32 r32 +// ADCL imm8 m32 +// ADCL imm32 m32 +// ADCL r32 m32 +func ADCL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ADCL: bad operands") +} + +// ADCQ: Add with Carry. +// +// Forms: +// +// ADCQ imm32 rax +// ADCQ imm8 r64 +// ADCQ imm32 r64 +// ADCQ r64 r64 +// ADCQ m64 r64 +// ADCQ imm8 m64 +// ADCQ imm32 m64 +// ADCQ r64 m64 +func ADCQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ADCQ: bad operands") +} + +// ADCW: Add with Carry. +// +// Forms: +// +// ADCW imm16 ax +// ADCW imm8 r16 +// ADCW imm16 r16 +// ADCW r16 r16 +// ADCW m16 r16 +// ADCW imm8 m16 +// ADCW imm16 m16 +// ADCW r16 m16 +func ADCW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADCW: bad operands") +} + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +func ADCXL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADCXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADCXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + } + return nil, errors.New("ADCXL: bad operands") +} + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +func ADCXQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADCXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADCXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + } + return nil, errors.New("ADCXQ: bad operands") +} + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +func ADDB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADDB: bad operands") +} + +// ADDL: Add. +// +// Forms: +// +// ADDL imm32 eax +// ADDL imm8 r32 +// ADDL imm32 r32 +// ADDL r32 r32 +// ADDL m32 r32 +// ADDL imm8 m32 +// ADDL imm32 m32 +// ADDL r32 m32 +func ADDL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ADDL: bad operands") +} + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +func ADDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("ADDPD: bad operands") +} + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +func ADDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("ADDPS: bad operands") +} + +// ADDQ: Add. +// +// Forms: +// +// ADDQ imm32 rax +// ADDQ imm8 r64 +// ADDQ imm32 r64 +// ADDQ r64 r64 +// ADDQ m64 r64 +// ADDQ imm8 m64 +// ADDQ imm32 m64 +// ADDQ r64 m64 +func ADDQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ADDQ: bad operands") +} + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +func ADDSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("ADDSD: bad operands") +} + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +func ADDSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("ADDSS: bad operands") +} + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +func ADDSUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("ADDSUBPD: bad operands") +} + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +func ADDSUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("ADDSUBPS: bad operands") +} + +// ADDW: Add. +// +// Forms: +// +// ADDW imm16 ax +// ADDW imm8 r16 +// ADDW imm16 r16 +// ADDW r16 r16 +// ADDW m16 r16 +// ADDW imm8 m16 +// ADDW imm16 m16 +// ADDW r16 m16 +func ADDW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADDW: bad operands") +} + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +func ADOXL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADOXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADOXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + } + return nil, errors.New("ADOXL: bad operands") +} + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +func ADOXQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADOXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADOXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"ADX"}, + }, nil + } + return nil, errors.New("ADOXQ: bad operands") +} + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +func AESDEC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDEC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDEC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESDEC: bad operands") +} + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +func AESDECLAST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDECLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDECLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESDECLAST: bad operands") +} + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +func AESENC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESENC: bad operands") +} + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +func AESENCLAST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENCLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENCLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESENCLAST: bad operands") +} + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +func AESIMC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESIMC: bad operands") +} + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +func AESKEYGENASSIST(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AES"}, + }, nil + } + return nil, errors.New("AESKEYGENASSIST: bad operands") +} + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +func ANDB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ANDB: bad operands") +} + +// ANDL: Logical AND. +// +// Forms: +// +// ANDL imm32 eax +// ANDL imm8 r32 +// ANDL imm32 r32 +// ANDL r32 r32 +// ANDL m32 r32 +// ANDL imm8 m32 +// ANDL imm32 m32 +// ANDL r32 m32 +func ANDL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ANDL: bad operands") +} + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +func ANDNL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "ANDNL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + CancellingInputs: true, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "ANDNL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("ANDNL: bad operands") +} + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +func ANDNPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("ANDNPD: bad operands") +} + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +func ANDNPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("ANDNPS: bad operands") +} + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +func ANDNQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "ANDNQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + CancellingInputs: true, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "ANDNQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("ANDNQ: bad operands") +} + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +func ANDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("ANDPD: bad operands") +} + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +func ANDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("ANDPS: bad operands") +} + +// ANDQ: Logical AND. +// +// Forms: +// +// ANDQ imm32 rax +// ANDQ imm8 r64 +// ANDQ imm32 r64 +// ANDQ r64 r64 +// ANDQ m64 r64 +// ANDQ imm8 m64 +// ANDQ imm32 m64 +// ANDQ r64 m64 +func ANDQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ANDQ: bad operands") +} + +// ANDW: Logical AND. +// +// Forms: +// +// ANDW imm16 ax +// ANDW imm8 r16 +// ANDW imm16 r16 +// ANDW r16 r16 +// ANDW m16 r16 +// ANDW imm8 m16 +// ANDW imm16 m16 +// ANDW r16 m16 +func ANDW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ANDW: bad operands") +} + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +func BEXTRL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BEXTRL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BEXTRL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BEXTRL: bad operands") +} + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +func BEXTRQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BEXTRQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BEXTRQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BEXTRQ: bad operands") +} + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +func BLENDPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("BLENDPD: bad operands") +} + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +func BLENDPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("BLENDPS: bad operands") +} + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +func BLENDVPD(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPD", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPD", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("BLENDVPD: bad operands") +} + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +func BLENDVPS(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPS", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPS", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("BLENDVPS: bad operands") +} + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +func BLSIL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSIL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSIL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSIL: bad operands") +} + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +func BLSIQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSIQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSIQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSIQ: bad operands") +} + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +func BLSMSKL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSMSKL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSMSKL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSMSKL: bad operands") +} + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +func BLSMSKQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSMSKQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSMSKQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSMSKQ: bad operands") +} + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +func BLSRL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSRL: bad operands") +} + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +func BLSRQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("BLSRQ: bad operands") +} + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +func BSFL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSFL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSFL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFL: bad operands") +} + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +func BSFQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSFQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSFQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFQ: bad operands") +} + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +func BSFW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSFW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSFW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFW: bad operands") +} + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +func BSRL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRL: bad operands") +} + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +func BSRQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRQ: bad operands") +} + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +func BSRW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSRW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSRW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRW: bad operands") +} + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +func BSWAPL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSWAPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSWAPL: bad operands") +} + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +func BSWAPQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSWAPQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSWAPQ: bad operands") +} + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +func BTCL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCL: bad operands") +} + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +func BTCQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCQ: bad operands") +} + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +func BTCW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCW: bad operands") +} + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +func BTL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTL: bad operands") +} + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +func BTQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTQ: bad operands") +} + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +func BTRL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRL: bad operands") +} + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +func BTRQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRQ: bad operands") +} + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +func BTRW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRW: bad operands") +} + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +func BTSL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSL: bad operands") +} + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +func BTSQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSQ: bad operands") +} + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +func BTSW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSW: bad operands") +} + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +func BTW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTW: bad operands") +} + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +func BZHIL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BZHIL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BZHIL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("BZHIL: bad operands") +} + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +func BZHIQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BZHIQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BZHIQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("BZHIQ: bad operands") +} + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +func CALL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "CALL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CALL: bad operands") +} + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +func CBW() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CBW", + Operands: nil, + Inputs: []operand.Op{reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil +} + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +func CDQ() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CDQ", + Operands: nil, + Inputs: []operand.Op{reg.EAX}, + Outputs: []operand.Op{reg.EDX}, + }, nil +} + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +func CDQE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CDQE", + Operands: nil, + Inputs: []operand.Op{reg.EAX}, + Outputs: []operand.Op{reg.RAX}, + }, nil +} + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +func CLC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CLC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +func CLD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CLD", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +func CLFLUSH(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "CLFLUSH", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"CLFLUSH"}, + }, nil + } + return nil, errors.New("CLFLUSH: bad operands") +} + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +func CLFLUSHOPT(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "CLFLUSHOPT", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"CLFLUSHOPT"}, + }, nil + } + return nil, errors.New("CLFLUSHOPT: bad operands") +} + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +func CMC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CMC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +func CMOVLCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLCC: bad operands") +} + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +func CMOVLCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLCS: bad operands") +} + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +func CMOVLEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLEQ: bad operands") +} + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +func CMOVLGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLGE: bad operands") +} + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +func CMOVLGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLGT: bad operands") +} + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +func CMOVLHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLHI: bad operands") +} + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +func CMOVLLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLLE: bad operands") +} + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +func CMOVLLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLLS: bad operands") +} + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +func CMOVLLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLLT: bad operands") +} + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +func CMOVLMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLMI: bad operands") +} + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +func CMOVLNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLNE: bad operands") +} + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +func CMOVLOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLOC: bad operands") +} + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +func CMOVLOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLOS: bad operands") +} + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +func CMOVLPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLPC: bad operands") +} + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +func CMOVLPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLPL: bad operands") +} + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +func CMOVLPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVLPS: bad operands") +} + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +func CMOVQCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQCC: bad operands") +} + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +func CMOVQCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQCS: bad operands") +} + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +func CMOVQEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQEQ: bad operands") +} + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +func CMOVQGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQGE: bad operands") +} + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +func CMOVQGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQGT: bad operands") +} + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +func CMOVQHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQHI: bad operands") +} + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +func CMOVQLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQLE: bad operands") +} + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +func CMOVQLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQLS: bad operands") +} + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +func CMOVQLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQLT: bad operands") +} + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +func CMOVQMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQMI: bad operands") +} + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +func CMOVQNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQNE: bad operands") +} + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +func CMOVQOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQOC: bad operands") +} + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +func CMOVQOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQOS: bad operands") +} + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +func CMOVQPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQPC: bad operands") +} + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +func CMOVQPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQPL: bad operands") +} + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +func CMOVQPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVQPS: bad operands") +} + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +func CMOVWCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWCC: bad operands") +} + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +func CMOVWCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWCS: bad operands") +} + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +func CMOVWEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWEQ: bad operands") +} + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +func CMOVWGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWGE: bad operands") +} + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +func CMOVWGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWGT: bad operands") +} + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +func CMOVWHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWHI: bad operands") +} + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +func CMOVWLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWLE: bad operands") +} + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +func CMOVWLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWLS: bad operands") +} + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +func CMOVWLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWLT: bad operands") +} + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +func CMOVWMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWMI: bad operands") +} + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +func CMOVWNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWNE: bad operands") +} + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +func CMOVWOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWOC: bad operands") +} + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +func CMOVWOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWOS: bad operands") +} + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +func CMOVWPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWPC: bad operands") +} + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +func CMOVWPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWPL: bad operands") +} + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +func CMOVWPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"CMOV"}, + }, nil + } + return nil, errors.New("CMOVWPS: bad operands") +} + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +func CMPB(amr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsAL(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(amr) && operand.IsR8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + CancellingInputs: true, + }, nil + case operand.IsR8(amr) && operand.IsM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM8(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM8(amr) && operand.IsR8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPB: bad operands") +} + +// CMPL: Compare Two Operands. +// +// Forms: +// +// CMPL eax imm32 +// CMPL r32 imm8 +// CMPL r32 imm32 +// CMPL r32 r32 +// CMPL r32 m32 +// CMPL m32 imm8 +// CMPL m32 imm32 +// CMPL m32 r32 +func CMPL(emr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsEAX(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsR32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + CancellingInputs: true, + }, nil + case operand.IsR32(emr) && operand.IsM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsR32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPL: bad operands") +} + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +func CMPPD(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CMPPD: bad operands") +} + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +func CMPPS(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CMPPS: bad operands") +} + +// CMPQ: Compare Two Operands. +// +// Forms: +// +// CMPQ rax imm32 +// CMPQ r64 imm8 +// CMPQ r64 imm32 +// CMPQ r64 r64 +// CMPQ r64 m64 +// CMPQ m64 imm8 +// CMPQ m64 imm32 +// CMPQ m64 r64 +func CMPQ(mr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsRAX(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + CancellingInputs: true, + }, nil + case operand.IsR64(mr) && operand.IsM64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPQ: bad operands") +} + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +func CMPSD(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CMPSD: bad operands") +} + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +func CMPSS(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CMPSS: bad operands") +} + +// CMPW: Compare Two Operands. +// +// Forms: +// +// CMPW ax imm16 +// CMPW r16 imm8 +// CMPW r16 imm16 +// CMPW r16 r16 +// CMPW r16 m16 +// CMPW m16 imm8 +// CMPW m16 imm16 +// CMPW m16 r16 +func CMPW(amr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsAX(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsR16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + CancellingInputs: true, + }, nil + case operand.IsR16(amr) && operand.IsM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsR16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPW: bad operands") +} + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +func CMPXCHG16B(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "CMPXCHG16B", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m, reg.RAX, reg.RBX, reg.RCX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("CMPXCHG16B: bad operands") +} + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +func CMPXCHG8B(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(m): + return &intrep.Instruction{ + Opcode: "CMPXCHG8B", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m, reg.EAX, reg.EBX, reg.ECX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("CMPXCHG8B: bad operands") +} + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +func CMPXCHGB(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(r) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(r) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGB: bad operands") +} + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +func CMPXCHGL(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGL: bad operands") +} + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +func CMPXCHGQ(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGQ: bad operands") +} + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +func CMPXCHGW(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(r) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGW: bad operands") +} + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +func COMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("COMISD: bad operands") +} + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +func COMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("COMISS: bad operands") +} + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +func CPUID() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CPUID", + Operands: nil, + Inputs: []operand.Op{reg.EAX, reg.ECX}, + Outputs: []operand.Op{reg.EAX, reg.EBX, reg.ECX, reg.EDX}, + ISA: []string{"CPUID"}, + }, nil +} + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +func CQO() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CQO", + Operands: nil, + Inputs: []operand.Op{reg.RAX}, + Outputs: []operand.Op{reg.RDX}, + }, nil +} + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +func CRC32B(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("CRC32B: bad operands") +} + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +func CRC32L(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32L", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32L", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("CRC32L: bad operands") +} + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +func CRC32Q(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32Q", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32Q", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("CRC32Q: bad operands") +} + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +func CRC32W(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32W", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32W", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("CRC32W: bad operands") +} + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +func CVTPD2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPD2PL: bad operands") +} + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +func CVTPD2PS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPD2PS: bad operands") +} + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +func CVTPL2PD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPL2PD: bad operands") +} + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +func CVTPL2PS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPL2PS: bad operands") +} + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +func CVTPS2PD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPS2PD: bad operands") +} + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +func CVTPS2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTPS2PL: bad operands") +} + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +func CVTSD2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTSD2SL: bad operands") +} + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +func CVTSD2SS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSD2SS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSD2SS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTSD2SS: bad operands") +} + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +func CVTSL2SD(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTSL2SD: bad operands") +} + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +func CVTSL2SS(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CVTSL2SS: bad operands") +} + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +func CVTSQ2SD(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTSQ2SD: bad operands") +} + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +func CVTSQ2SS(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CVTSQ2SS: bad operands") +} + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +func CVTSS2SD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSS2SD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSS2SD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTSS2SD: bad operands") +} + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +func CVTSS2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CVTSS2SL: bad operands") +} + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +func CVTTPD2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTTPD2PL: bad operands") +} + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +func CVTTPS2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTTPS2PL: bad operands") +} + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +func CVTTSD2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTTSD2SL: bad operands") +} + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +func CVTTSD2SQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("CVTTSD2SQ: bad operands") +} + +// CVTTSS2SL: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTTSS2SL xmm r32 +// CVTTSS2SL m32 r32 +// CVTTSS2SL xmm r64 +// CVTTSS2SL m32 r64 +func CVTTSS2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("CVTTSS2SL: bad operands") +} + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +func CWD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CWD", + Operands: nil, + Inputs: []operand.Op{reg.AX}, + Outputs: []operand.Op{reg.DX}, + }, nil +} + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +func CWDE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CWDE", + Operands: nil, + Inputs: []operand.Op{reg.AX}, + Outputs: []operand.Op{reg.EAX}, + }, nil +} + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +func DECB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "DECB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "DECB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECB: bad operands") +} + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +func DECL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "DECL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "DECL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECL: bad operands") +} + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +func DECQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "DECQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "DECQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECQ: bad operands") +} + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +func DECW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "DECW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "DECW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECW: bad operands") +} + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +func DIVB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "DIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "DIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("DIVB: bad operands") +} + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +func DIVL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "DIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "DIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("DIVL: bad operands") +} + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +func DIVPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("DIVPD: bad operands") +} + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +func DIVPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("DIVPS: bad operands") +} + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +func DIVQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "DIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "DIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("DIVQ: bad operands") +} + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +func DIVSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("DIVSD: bad operands") +} + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +func DIVSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("DIVSS: bad operands") +} + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +func DIVW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "DIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "DIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("DIVW: bad operands") +} + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +func DPPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("DPPD: bad operands") +} + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +func DPPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("DPPS: bad operands") +} + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +func EXTRACTPS(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM2U(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "EXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM2U(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "EXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("EXTRACTPS: bad operands") +} + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +func HADDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("HADDPD: bad operands") +} + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +func HADDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("HADDPS: bad operands") +} + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +func HSUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("HSUBPD: bad operands") +} + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +func HSUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("HSUBPS: bad operands") +} + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +func IDIVB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "IDIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "IDIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("IDIVB: bad operands") +} + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +func IDIVL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "IDIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "IDIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("IDIVL: bad operands") +} + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +func IDIVQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "IDIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "IDIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("IDIVQ: bad operands") +} + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +func IDIVW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "IDIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "IDIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("IDIVW: bad operands") +} + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +func IMUL3L(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3L: bad operands") +} + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +func IMUL3Q(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3Q: bad operands") +} + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +func IMUL3W(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM16(i) && operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM16(i) && operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3W: bad operands") +} + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +func IMULB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "IMULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "IMULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("IMULB: bad operands") +} + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +func IMULL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR32(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case len(ops) == 1 && operand.IsM32(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case len(ops) == 2 && operand.IsR32(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM32(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULL: bad operands") +} + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +func IMULQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR64(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case len(ops) == 1 && operand.IsM64(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case len(ops) == 2 && operand.IsR64(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM64(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULQ: bad operands") +} + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +func IMULW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR16(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case len(ops) == 1 && operand.IsM16(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case len(ops) == 2 && operand.IsR16(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM16(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULW: bad operands") +} + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +func INCB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "INCB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "INCB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCB: bad operands") +} + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +func INCL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "INCL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "INCL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCL: bad operands") +} + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +func INCQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "INCQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "INCQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCQ: bad operands") +} + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +func INCW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "INCW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "INCW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCW: bad operands") +} + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +func INSERTPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "INSERTPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "INSERTPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("INSERTPS: bad operands") +} + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +func INT(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is3(i): + return &intrep.Instruction{ + Opcode: "INT", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "INT", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("INT: bad operands") +} + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +func JA(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JA: bad operands") +} + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +func JAE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JAE: bad operands") +} + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +func JB(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JB: bad operands") +} + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +func JBE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JBE: bad operands") +} + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +func JC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JC: bad operands") +} + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +func JCC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JCC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCC: bad operands") +} + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +func JCS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JCS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCS: bad operands") +} + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +func JCXZL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCXZL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{reg.ECX}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCXZL: bad operands") +} + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +func JCXZQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCXZQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{reg.RCX}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCXZQ: bad operands") +} + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +func JE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JE: bad operands") +} + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +func JEQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JEQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JEQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JEQ: bad operands") +} + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +func JG(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JG: bad operands") +} + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +func JGE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JGE: bad operands") +} + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +func JGT(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JGT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JGT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JGT: bad operands") +} + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +func JHI(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JHI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JHI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JHI: bad operands") +} + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +func JHS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JHS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JHS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JHS: bad operands") +} + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +func JL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JL: bad operands") +} + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +func JLE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLE: bad operands") +} + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +func JLO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLO: bad operands") +} + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +func JLS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLS: bad operands") +} + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +func JLT(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLT: bad operands") +} + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +func JMI(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JMI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JMI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JMI: bad operands") +} + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +func JMP(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsREL32(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + } + return nil, errors.New("JMP: bad operands") +} + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +func JNA(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNA: bad operands") +} + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +func JNAE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNAE: bad operands") +} + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +func JNB(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNB: bad operands") +} + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +func JNBE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNBE: bad operands") +} + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +func JNC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNC: bad operands") +} + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +func JNE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNE: bad operands") +} + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +func JNG(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNG: bad operands") +} + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +func JNGE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNGE: bad operands") +} + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +func JNL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNL: bad operands") +} + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +func JNLE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNLE: bad operands") +} + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +func JNO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNO: bad operands") +} + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +func JNP(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNP: bad operands") +} + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +func JNS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNS: bad operands") +} + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +func JNZ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNZ: bad operands") +} + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +func JO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JO: bad operands") +} + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +func JOC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JOC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JOC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JOC: bad operands") +} + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +func JOS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JOS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JOS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JOS: bad operands") +} + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +func JP(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JP: bad operands") +} + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +func JPC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPC: bad operands") +} + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +func JPE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPE: bad operands") +} + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +func JPL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPL: bad operands") +} + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +func JPO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPO: bad operands") +} + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +func JPS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPS: bad operands") +} + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +func JS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JS: bad operands") +} + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +func JZ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JZ: bad operands") +} + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +func LDDQU(m, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "LDDQU", + Operands: []operand.Op{m, x}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("LDDQU: bad operands") +} + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +func LDMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "LDMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("LDMXCSR: bad operands") +} + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +func LEAL(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LEAL", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAL: bad operands") +} + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +func LEAQ(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LEAQ", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAQ: bad operands") +} + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +func LEAW(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LEAW", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAW: bad operands") +} + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +func LFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "LFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil +} + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +func LZCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + } + return nil, errors.New("LZCNTL: bad operands") +} + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +func LZCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + } + return nil, errors.New("LZCNTQ: bad operands") +} + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +func LZCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"LZCNT"}, + }, nil + } + return nil, errors.New("LZCNTW: bad operands") +} + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +func MASKMOVDQU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MASKMOVDQU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MASKMOVDQU: bad operands") +} + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +func MASKMOVOU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MASKMOVOU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MASKMOVOU: bad operands") +} + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +func MAXPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MAXPD: bad operands") +} + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +func MAXPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MAXPS: bad operands") +} + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +func MAXSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MAXSD: bad operands") +} + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +func MAXSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MAXSS: bad operands") +} + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +func MFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil +} + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +func MINPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MINPD: bad operands") +} + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +func MINPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MINPS: bad operands") +} + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +func MINSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MINSD: bad operands") +} + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +func MINSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MINSS: bad operands") +} + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +func MONITOR() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MONITOR", + Operands: nil, + Inputs: []operand.Op{reg.RAX, reg.ECX, reg.EDX}, + Outputs: []operand.Op{}, + ISA: []string{"MONITOR"}, + }, nil +} + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +func MOVAPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVAPD: bad operands") +} + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +func MOVAPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVAPS: bad operands") +} + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +func MOVB(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVB: bad operands") +} + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +func MOVBELL(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(mr) && operand.IsR32(mr1): + return &intrep.Instruction{ + Opcode: "MOVBELL", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + case operand.IsR32(mr) && operand.IsM32(mr1): + return &intrep.Instruction{ + Opcode: "MOVBELL", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + } + return nil, errors.New("MOVBELL: bad operands") +} + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +func MOVBEQQ(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEQQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + case operand.IsR64(mr) && operand.IsM64(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEQQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + } + return nil, errors.New("MOVBEQQ: bad operands") +} + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +func MOVBEWW(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM16(mr) && operand.IsR16(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEWW", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + case operand.IsR16(mr) && operand.IsM16(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEWW", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + ISA: []string{"MOVBE"}, + }, nil + } + return nil, errors.New("MOVBEWW: bad operands") +} + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +func MOVBLSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBLSX: bad operands") +} + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +func MOVBLZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBLZX: bad operands") +} + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +func MOVBQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBQSX: bad operands") +} + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +func MOVBQZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBQZX: bad operands") +} + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +func MOVBWSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBWSX: bad operands") +} + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +func MOVBWZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBWZX: bad operands") +} + +// MOVD: Move. +// +// Forms: +// +// MOVD imm32 r64 +// MOVD imm64 r64 +// MOVD r64 r64 +// MOVD m64 r64 +// MOVD imm32 m64 +// MOVD r64 m64 +// MOVD xmm r64 +// MOVD r64 xmm +// MOVD xmm xmm +// MOVD m64 xmm +// MOVD xmm m64 +// MOVD xmm r32 +// MOVD r32 xmm +// MOVD m32 xmm +// MOVD xmm m32 +func MOVD(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVD: bad operands") +} + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +func MOVDDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVDDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVDDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("MOVDDUP: bad operands") +} + +// MOVDQ2Q: Move. +// +// Forms: +// +// MOVDQ2Q imm32 r64 +// MOVDQ2Q imm64 r64 +// MOVDQ2Q r64 r64 +// MOVDQ2Q m64 r64 +// MOVDQ2Q imm32 m64 +// MOVDQ2Q r64 m64 +// MOVDQ2Q xmm r64 +// MOVDQ2Q r64 xmm +// MOVDQ2Q xmm xmm +// MOVDQ2Q m64 xmm +// MOVDQ2Q xmm m64 +// MOVDQ2Q xmm r32 +// MOVDQ2Q r32 xmm +// MOVDQ2Q m32 xmm +// MOVDQ2Q xmm m32 +func MOVDQ2Q(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVDQ2Q: bad operands") +} + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +func MOVHLPS(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MOVHLPS", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVHLPS: bad operands") +} + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +func MOVHPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVHPD: bad operands") +} + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +func MOVHPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVHPS: bad operands") +} + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +func MOVL(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVL: bad operands") +} + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +func MOVLHPS(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MOVLHPS", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVLHPS: bad operands") +} + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +func MOVLPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVLPD: bad operands") +} + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +func MOVLPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVLPS: bad operands") +} + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +func MOVLQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVLQSX: bad operands") +} + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +func MOVLQZX(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQZX", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVLQZX: bad operands") +} + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +func MOVMSKPD(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVMSKPD", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVMSKPD: bad operands") +} + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +func MOVMSKPS(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVMSKPS", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVMSKPS: bad operands") +} + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +func MOVNTDQ(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTDQ", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVNTDQ: bad operands") +} + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +func MOVNTDQA(m, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVNTDQA", + Operands: []operand.Op{m, x}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("MOVNTDQA: bad operands") +} + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +func MOVNTIL(r, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "MOVNTIL", + Operands: []operand.Op{r, m}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVNTIL: bad operands") +} + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +func MOVNTIQ(r, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsM64(m): + return &intrep.Instruction{ + Opcode: "MOVNTIQ", + Operands: []operand.Op{r, m}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVNTIQ: bad operands") +} + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +func MOVNTO(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTO", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVNTO: bad operands") +} + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +func MOVNTPD(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTPD", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVNTPD: bad operands") +} + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +func MOVNTPS(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTPS", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVNTPS: bad operands") +} + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +func MOVO(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVO: bad operands") +} + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +func MOVOA(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVOA: bad operands") +} + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +func MOVOU(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVOU: bad operands") +} + +// MOVQ: Move. +// +// Forms: +// +// MOVQ imm32 r64 +// MOVQ imm64 r64 +// MOVQ r64 r64 +// MOVQ m64 r64 +// MOVQ imm32 m64 +// MOVQ r64 m64 +// MOVQ xmm r64 +// MOVQ r64 xmm +// MOVQ xmm xmm +// MOVQ m64 xmm +// MOVQ xmm m64 +// MOVQ xmm r32 +// MOVQ r32 xmm +// MOVQ m32 xmm +// MOVQ xmm m32 +func MOVQ(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVQ: bad operands") +} + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +func MOVSD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVSD: bad operands") +} + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +func MOVSHDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSHDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSHDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("MOVSHDUP: bad operands") +} + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +func MOVSLDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSLDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSLDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE3"}, + }, nil + } + return nil, errors.New("MOVSLDUP: bad operands") +} + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +func MOVSS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsM32(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVSS: bad operands") +} + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +func MOVUPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MOVUPD: bad operands") +} + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +func MOVUPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MOVUPS: bad operands") +} + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +func MOVW(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVW: bad operands") +} + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +func MOVWLSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWLSX: bad operands") +} + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +func MOVWLZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWLZX: bad operands") +} + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +func MOVWQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWQSX: bad operands") +} + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +func MOVWQZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWQZX: bad operands") +} + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +func MPSADBW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MPSADBW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MPSADBW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("MPSADBW: bad operands") +} + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +func MULB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("MULB: bad operands") +} + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +func MULL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MULL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MULL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("MULL: bad operands") +} + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +func MULPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MULPD: bad operands") +} + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +func MULPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MULPS: bad operands") +} + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +func MULQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "MULQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "MULQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("MULQ: bad operands") +} + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +func MULSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("MULSD: bad operands") +} + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +func MULSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("MULSS: bad operands") +} + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +func MULW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MULW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MULW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("MULW: bad operands") +} + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +func MULXL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "MULXL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.EDX}, + Outputs: []operand.Op{r, r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "MULXL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.EDX}, + Outputs: []operand.Op{r, r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("MULXL: bad operands") +} + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +func MULXQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "MULXQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.RDX}, + Outputs: []operand.Op{r, r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "MULXQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.RDX}, + Outputs: []operand.Op{r, r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("MULXQ: bad operands") +} + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +func MWAIT() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MWAIT", + Operands: nil, + Inputs: []operand.Op{reg.EAX, reg.ECX}, + Outputs: []operand.Op{}, + ISA: []string{"MONITOR"}, + }, nil +} + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +func NEGB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "NEGB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "NEGB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGB: bad operands") +} + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +func NEGL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "NEGL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "NEGL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGL: bad operands") +} + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +func NEGQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "NEGQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "NEGQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGQ: bad operands") +} + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +func NEGW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "NEGW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "NEGW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGW: bad operands") +} + +// NOP: No Operation. +// +// Forms: +// +// NOP +func NOP() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "NOP", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +func NOTB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "NOTB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "NOTB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTB: bad operands") +} + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +func NOTL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "NOTL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "NOTL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTL: bad operands") +} + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +func NOTQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "NOTQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "NOTQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTQ: bad operands") +} + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +func NOTW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "NOTW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "NOTW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTW: bad operands") +} + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +func ORB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ORB: bad operands") +} + +// ORL: Logical Inclusive OR. +// +// Forms: +// +// ORL imm32 eax +// ORL imm8 r32 +// ORL imm32 r32 +// ORL r32 r32 +// ORL m32 r32 +// ORL imm8 m32 +// ORL imm32 m32 +// ORL r32 m32 +func ORL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ORL: bad operands") +} + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +func ORPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("ORPD: bad operands") +} + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +func ORPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("ORPS: bad operands") +} + +// ORQ: Logical Inclusive OR. +// +// Forms: +// +// ORQ imm32 rax +// ORQ imm8 r64 +// ORQ imm32 r64 +// ORQ r64 r64 +// ORQ m64 r64 +// ORQ imm8 m64 +// ORQ imm32 m64 +// ORQ r64 m64 +func ORQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ORQ: bad operands") +} + +// ORW: Logical Inclusive OR. +// +// Forms: +// +// ORW imm16 ax +// ORW imm8 r16 +// ORW imm16 r16 +// ORW r16 r16 +// ORW m16 r16 +// ORW imm8 m16 +// ORW imm16 m16 +// ORW r16 m16 +func ORW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ORW: bad operands") +} + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +func PABSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PABSB: bad operands") +} + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +func PABSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PABSD: bad operands") +} + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +func PABSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PABSW: bad operands") +} + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +func PACKSSLW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PACKSSLW: bad operands") +} + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +func PACKSSWB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PACKSSWB: bad operands") +} + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +func PACKUSDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PACKUSDW: bad operands") +} + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +func PACKUSWB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PACKUSWB: bad operands") +} + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +func PADDB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDB: bad operands") +} + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +func PADDD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDD: bad operands") +} + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +func PADDL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDL: bad operands") +} + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +func PADDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDQ: bad operands") +} + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +func PADDSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDSB: bad operands") +} + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +func PADDSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDSW: bad operands") +} + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +func PADDUSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDUSB: bad operands") +} + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +func PADDUSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDUSW: bad operands") +} + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +func PADDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PADDW: bad operands") +} + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +func PALIGNR(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PALIGNR", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PALIGNR", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PALIGNR: bad operands") +} + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +func PAND(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PAND: bad operands") +} + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +func PANDN(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PANDN", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PANDN", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PANDN: bad operands") +} + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +func PAUSE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "PAUSE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +func PAVGB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PAVGB: bad operands") +} + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +func PAVGW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PAVGW: bad operands") +} + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +func PBLENDVB(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "PBLENDVB", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "PBLENDVB", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PBLENDVB: bad operands") +} + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +func PBLENDW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PBLENDW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PBLENDW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PBLENDW: bad operands") +} + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +func PCLMULQDQ(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCLMULQDQ", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"PCLMULQDQ"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCLMULQDQ", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"PCLMULQDQ"}, + }, nil + } + return nil, errors.New("PCLMULQDQ: bad operands") +} + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +func PCMPEQB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPEQB: bad operands") +} + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +func PCMPEQL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPEQL: bad operands") +} + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +func PCMPEQQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PCMPEQQ: bad operands") +} + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +func PCMPEQW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPEQW: bad operands") +} + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +func PCMPESTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("PCMPESTRI: bad operands") +} + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +func PCMPESTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("PCMPESTRM: bad operands") +} + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +func PCMPGTB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPGTB: bad operands") +} + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +func PCMPGTL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPGTL: bad operands") +} + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +func PCMPGTQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("PCMPGTQ: bad operands") +} + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +func PCMPGTW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PCMPGTW: bad operands") +} + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +func PCMPISTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("PCMPISTRI: bad operands") +} + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +func PCMPISTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"SSE4.2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"SSE4.2"}, + }, nil + } + return nil, errors.New("PCMPISTRM: bad operands") +} + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +func PDEPL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PDEPL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PDEPL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("PDEPL: bad operands") +} + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +func PDEPQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PDEPQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PDEPQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("PDEPQ: bad operands") +} + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +func PEXTL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PEXTL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PEXTL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("PEXTL: bad operands") +} + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +func PEXTQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PEXTQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PEXTQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("PEXTQ: bad operands") +} + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +func PEXTRB(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "PEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PEXTRB: bad operands") +} + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +func PEXTRD(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PEXTRD: bad operands") +} + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +func PEXTRQ(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "PEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "PEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PEXTRQ: bad operands") +} + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +func PEXTRW(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "PEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PEXTRW: bad operands") +} + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +func PHADDD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHADDD: bad operands") +} + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +func PHADDSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHADDSW: bad operands") +} + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +func PHADDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHADDW: bad operands") +} + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +func PHMINPOSUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PHMINPOSUW: bad operands") +} + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +func PHSUBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHSUBD: bad operands") +} + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +func PHSUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHSUBSW: bad operands") +} + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +func PHSUBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PHSUBW: bad operands") +} + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +func PINSRB(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRB", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM8(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRB", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PINSRB: bad operands") +} + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +func PINSRD(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRD", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRD", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PINSRD: bad operands") +} + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +func PINSRQ(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRQ", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRQ", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PINSRQ: bad operands") +} + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +func PINSRW(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRW", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRW", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PINSRW: bad operands") +} + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +func PMADDUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PMADDUBSW: bad operands") +} + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +func PMADDWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMADDWL: bad operands") +} + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +func PMAXSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMAXSB: bad operands") +} + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +func PMAXSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMAXSD: bad operands") +} + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +func PMAXSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMAXSW: bad operands") +} + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +func PMAXUB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMAXUB: bad operands") +} + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +func PMAXUD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMAXUD: bad operands") +} + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +func PMAXUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMAXUW: bad operands") +} + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +func PMINSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMINSB: bad operands") +} + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +func PMINSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMINSD: bad operands") +} + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +func PMINSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMINSW: bad operands") +} + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +func PMINUB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMINUB: bad operands") +} + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +func PMINUD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMINUD: bad operands") +} + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +func PMINUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMINUW: bad operands") +} + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +func PMOVMSKB(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "PMOVMSKB", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMOVMSKB: bad operands") +} + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +func PMOVSXBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXBD: bad operands") +} + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +func PMOVSXBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXBQ: bad operands") +} + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +func PMOVSXBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXBW: bad operands") +} + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +func PMOVSXDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXDQ: bad operands") +} + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +func PMOVSXWD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXWD: bad operands") +} + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +func PMOVSXWQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVSXWQ: bad operands") +} + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +func PMOVZXBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXBD: bad operands") +} + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +func PMOVZXBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXBQ: bad operands") +} + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +func PMOVZXBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXBW: bad operands") +} + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +func PMOVZXDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXDQ: bad operands") +} + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +func PMOVZXWD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXWD: bad operands") +} + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +func PMOVZXWQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMOVZXWQ: bad operands") +} + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +func PMULDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMULDQ: bad operands") +} + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +func PMULHRSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHRSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHRSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PMULHRSW: bad operands") +} + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +func PMULHUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMULHUW: bad operands") +} + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +func PMULHW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMULHW: bad operands") +} + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +func PMULLD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PMULLD: bad operands") +} + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +func PMULLW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMULLW: bad operands") +} + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +func PMULULQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULULQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULULQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PMULULQ: bad operands") +} + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +func POPCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "POPCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "POPCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + } + return nil, errors.New("POPCNTL: bad operands") +} + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +func POPCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "POPCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "POPCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + } + return nil, errors.New("POPCNTQ: bad operands") +} + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +func POPCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "POPCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "POPCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"POPCNT"}, + }, nil + } + return nil, errors.New("POPCNTW: bad operands") +} + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +func POPQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "POPQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "POPQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("POPQ: bad operands") +} + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +func POPW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "POPW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "POPW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("POPW: bad operands") +} + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +func POR(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "POR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "POR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("POR: bad operands") +} + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +func PREFETCHNTA(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHNTA", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"MMX+"}, + }, nil + } + return nil, errors.New("PREFETCHNTA: bad operands") +} + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +func PREFETCHT0(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT0", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"MMX+"}, + }, nil + } + return nil, errors.New("PREFETCHT0: bad operands") +} + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +func PREFETCHT1(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT1", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"MMX+"}, + }, nil + } + return nil, errors.New("PREFETCHT1: bad operands") +} + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +func PREFETCHT2(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT2", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"MMX+"}, + }, nil + } + return nil, errors.New("PREFETCHT2: bad operands") +} + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +func PSADBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSADBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSADBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSADBW: bad operands") +} + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +func PSHUFB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PSHUFB: bad operands") +} + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +func PSHUFD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSHUFD: bad operands") +} + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +func PSHUFHW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFHW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFHW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSHUFHW: bad operands") +} + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +func PSHUFL(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFL", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFL", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSHUFL: bad operands") +} + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +func PSHUFLW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFLW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFLW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSHUFLW: bad operands") +} + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +func PSIGNB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PSIGNB: bad operands") +} + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +func PSIGND(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PSIGND: bad operands") +} + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +func PSIGNW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSSE3"}, + }, nil + } + return nil, errors.New("PSIGNW: bad operands") +} + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +func PSLLDQ(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLDQ", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSLLDQ: bad operands") +} + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +func PSLLL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSLLL: bad operands") +} + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +func PSLLO(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLO", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSLLO: bad operands") +} + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +func PSLLQ(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSLLQ: bad operands") +} + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +func PSLLW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSLLW: bad operands") +} + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +func PSRAL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRAL: bad operands") +} + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +func PSRAW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRAW: bad operands") +} + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +func PSRLDQ(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLDQ", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRLDQ: bad operands") +} + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +func PSRLL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRLL: bad operands") +} + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +func PSRLO(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLO", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRLO: bad operands") +} + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +func PSRLQ(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRLQ: bad operands") +} + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +func PSRLW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSRLW: bad operands") +} + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +func PSUBB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBB: bad operands") +} + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +func PSUBL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBL: bad operands") +} + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +func PSUBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBQ: bad operands") +} + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +func PSUBSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBSB: bad operands") +} + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +func PSUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBSW: bad operands") +} + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +func PSUBUSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBUSB: bad operands") +} + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +func PSUBUSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBUSW: bad operands") +} + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +func PSUBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PSUBW: bad operands") +} + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +func PTEST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PTEST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PTEST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("PTEST: bad operands") +} + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +func PUNPCKHBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKHBW: bad operands") +} + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +func PUNPCKHLQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKHLQ: bad operands") +} + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +func PUNPCKHQDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKHQDQ: bad operands") +} + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +func PUNPCKHWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKHWL: bad operands") +} + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +func PUNPCKLBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKLBW: bad operands") +} + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +func PUNPCKLLQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKLLQ: bad operands") +} + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +func PUNPCKLQDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKLQDQ: bad operands") +} + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +func PUNPCKLWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PUNPCKLWL: bad operands") +} + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +func PUSHQ(imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PUSHQ: bad operands") +} + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +func PUSHW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "PUSHW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "PUSHW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PUSHW: bad operands") +} + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +func PXOR(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PXOR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PXOR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("PXOR: bad operands") +} + +// RCLB: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLB 1 r8 +// RCLB imm8 r8 +// RCLB cl r8 +// RCLB 1 m8 +// RCLB imm8 m8 +// RCLB cl m8 +func RCLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLB: bad operands") +} + +// RCLL: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLL 1 r32 +// RCLL imm8 r32 +// RCLL cl r32 +// RCLL 1 m32 +// RCLL imm8 m32 +// RCLL cl m32 +func RCLL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLL: bad operands") +} + +// RCLQ: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLQ 1 r64 +// RCLQ imm8 r64 +// RCLQ cl r64 +// RCLQ 1 m64 +// RCLQ imm8 m64 +// RCLQ cl m64 +func RCLQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLQ: bad operands") +} + +// RCLW: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLW 1 r16 +// RCLW imm8 r16 +// RCLW cl r16 +// RCLW 1 m16 +// RCLW imm8 m16 +// RCLW cl m16 +func RCLW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLW: bad operands") +} + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +func RCPPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("RCPPS: bad operands") +} + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +func RCPSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("RCPSS: bad operands") +} + +// RCRB: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRB 1 r8 +// RCRB imm8 r8 +// RCRB cl r8 +// RCRB 1 m8 +// RCRB imm8 m8 +// RCRB cl m8 +func RCRB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRB: bad operands") +} + +// RCRL: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRL 1 r32 +// RCRL imm8 r32 +// RCRL cl r32 +// RCRL 1 m32 +// RCRL imm8 m32 +// RCRL cl m32 +func RCRL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRL: bad operands") +} + +// RCRQ: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRQ 1 r64 +// RCRQ imm8 r64 +// RCRQ cl r64 +// RCRQ 1 m64 +// RCRQ imm8 m64 +// RCRQ cl m64 +func RCRQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRQ: bad operands") +} + +// RCRW: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRW 1 r16 +// RCRW imm8 r16 +// RCRW cl r16 +// RCRW 1 m16 +// RCRW imm8 m16 +// RCRW cl m16 +func RCRW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRW: bad operands") +} + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +func RDRANDL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RDRANDL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDRAND"}, + }, nil + } + return nil, errors.New("RDRANDL: bad operands") +} + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +func RDRANDQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RDRANDQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDRAND"}, + }, nil + } + return nil, errors.New("RDRANDQ: bad operands") +} + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +func RDRANDW(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "RDRANDW", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDRAND"}, + }, nil + } + return nil, errors.New("RDRANDW: bad operands") +} + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +func RDSEEDL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RDSEEDL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDSEED"}, + }, nil + } + return nil, errors.New("RDSEEDL: bad operands") +} + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +func RDSEEDQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RDSEEDQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDSEED"}, + }, nil + } + return nil, errors.New("RDSEEDQ: bad operands") +} + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +func RDSEEDW(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "RDSEEDW", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + ISA: []string{"RDSEED"}, + }, nil + } + return nil, errors.New("RDSEEDW: bad operands") +} + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +func RDTSC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RDTSC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + ISA: []string{"RDTSC"}, + }, nil +} + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +func RDTSCP() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RDTSCP", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.EAX, reg.ECX, reg.EDX}, + ISA: []string{"RDTSCP"}, + }, nil +} + +// RET: Return from Procedure. +// +// Forms: +// +// RET +func RET() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RET", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsTerminal: true, + }, nil +} + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +func RETFL(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFL", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFL: bad operands") +} + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +func RETFQ(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFQ", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFQ: bad operands") +} + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +func RETFW(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFW", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFW: bad operands") +} + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +func ROLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLB: bad operands") +} + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +func ROLL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLL: bad operands") +} + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +func ROLQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLQ: bad operands") +} + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +func ROLW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLW: bad operands") +} + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +func RORB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORB: bad operands") +} + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +func RORL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORL: bad operands") +} + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +func RORQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORQ: bad operands") +} + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +func RORW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORW: bad operands") +} + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +func RORXL(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RORXL", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RORXL", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("RORXL: bad operands") +} + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +func RORXQ(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RORXQ", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RORXQ", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("RORXQ: bad operands") +} + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +func ROUNDPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("ROUNDPD: bad operands") +} + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +func ROUNDPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("ROUNDPS: bad operands") +} + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +func ROUNDSD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("ROUNDSD: bad operands") +} + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +func ROUNDSS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE4.1"}, + }, nil + } + return nil, errors.New("ROUNDSS: bad operands") +} + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +func RSQRTPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("RSQRTPS: bad operands") +} + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +func RSQRTSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("RSQRTSS: bad operands") +} + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +func SALB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALB: bad operands") +} + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +func SALL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALL: bad operands") +} + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +func SALQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALQ: bad operands") +} + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +func SALW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALW: bad operands") +} + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +func SARB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARB: bad operands") +} + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +func SARL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARL: bad operands") +} + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +func SARQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARQ: bad operands") +} + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +func SARW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARW: bad operands") +} + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +func SARXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SARXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SARXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SARXL: bad operands") +} + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +func SARXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SARXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SARXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SARXQ: bad operands") +} + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +func SBBB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SBBB: bad operands") +} + +// SBBL: Subtract with Borrow. +// +// Forms: +// +// SBBL imm32 eax +// SBBL imm8 r32 +// SBBL imm32 r32 +// SBBL r32 r32 +// SBBL m32 r32 +// SBBL imm8 m32 +// SBBL imm32 m32 +// SBBL r32 m32 +func SBBL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + CancellingInputs: true, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("SBBL: bad operands") +} + +// SBBQ: Subtract with Borrow. +// +// Forms: +// +// SBBQ imm32 rax +// SBBQ imm8 r64 +// SBBQ imm32 r64 +// SBBQ r64 r64 +// SBBQ m64 r64 +// SBBQ imm8 m64 +// SBBQ imm32 m64 +// SBBQ r64 m64 +func SBBQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + CancellingInputs: true, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SBBQ: bad operands") +} + +// SBBW: Subtract with Borrow. +// +// Forms: +// +// SBBW imm16 ax +// SBBW imm8 r16 +// SBBW imm16 r16 +// SBBW r16 r16 +// SBBW m16 r16 +// SBBW imm8 m16 +// SBBW imm16 m16 +// SBBW r16 m16 +func SBBW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SBBW: bad operands") +} + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +func SETCC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETCC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETCC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETCC: bad operands") +} + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +func SETCS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETCS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETCS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETCS: bad operands") +} + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +func SETEQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETEQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETEQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETEQ: bad operands") +} + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +func SETGE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETGE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETGE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETGE: bad operands") +} + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +func SETGT(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETGT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETGT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETGT: bad operands") +} + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +func SETHI(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETHI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETHI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETHI: bad operands") +} + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +func SETLE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLE: bad operands") +} + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +func SETLS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLS: bad operands") +} + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +func SETLT(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLT: bad operands") +} + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +func SETMI(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETMI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETMI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETMI: bad operands") +} + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +func SETNE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETNE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETNE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETNE: bad operands") +} + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +func SETOC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETOC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETOC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETOC: bad operands") +} + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +func SETOS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETOS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETOS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETOS: bad operands") +} + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +func SETPC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPC: bad operands") +} + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +func SETPL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPL: bad operands") +} + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +func SETPS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPS: bad operands") +} + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +func SFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "SFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + ISA: []string{"MMX+"}, + }, nil +} + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +func SHA1MSG1(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA1MSG1: bad operands") +} + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +func SHA1MSG2(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA1MSG2: bad operands") +} + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +func SHA1NEXTE(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1NEXTE", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1NEXTE", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA1NEXTE: bad operands") +} + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +func SHA1RNDS4(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM2U(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1RNDS4", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsIMM2U(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1RNDS4", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA1RNDS4: bad operands") +} + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +func SHA256MSG1(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA256MSG1: bad operands") +} + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +func SHA256MSG2(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA256MSG2: bad operands") +} + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +func SHA256RNDS2(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "SHA256RNDS2", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SHA"}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "SHA256RNDS2", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"SHA"}, + }, nil + } + return nil, errors.New("SHA256RNDS2: bad operands") +} + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +func SHLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SHLB: bad operands") +} + +// SHLL: Logical Shift Left. +// +// Forms: +// +// SHLL 1 r32 +// SHLL imm8 r32 +// SHLL cl r32 +// SHLL 1 m32 +// SHLL imm8 m32 +// SHLL cl m32 +// SHLL imm8 r32 r32 +// SHLL cl r32 r32 +// SHLL imm8 r32 m32 +// SHLL cl r32 m32 +func SHLL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLL: bad operands") +} + +// SHLQ: Logical Shift Left. +// +// Forms: +// +// SHLQ 1 r64 +// SHLQ imm8 r64 +// SHLQ cl r64 +// SHLQ 1 m64 +// SHLQ imm8 m64 +// SHLQ cl m64 +// SHLQ imm8 r64 r64 +// SHLQ cl r64 r64 +// SHLQ imm8 r64 m64 +// SHLQ cl r64 m64 +func SHLQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLQ: bad operands") +} + +// SHLW: Logical Shift Left. +// +// Forms: +// +// SHLW 1 r16 +// SHLW imm8 r16 +// SHLW cl r16 +// SHLW 1 m16 +// SHLW imm8 m16 +// SHLW cl m16 +// SHLW imm8 r16 r16 +// SHLW cl r16 r16 +// SHLW imm8 r16 m16 +// SHLW cl r16 m16 +func SHLW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLW: bad operands") +} + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +func SHLXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHLXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHLXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SHLXL: bad operands") +} + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +func SHLXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHLXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHLXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SHLXQ: bad operands") +} + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +func SHRB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SHRB: bad operands") +} + +// SHRL: Logical Shift Right. +// +// Forms: +// +// SHRL 1 r32 +// SHRL imm8 r32 +// SHRL cl r32 +// SHRL 1 m32 +// SHRL imm8 m32 +// SHRL cl m32 +// SHRL imm8 r32 r32 +// SHRL cl r32 r32 +// SHRL imm8 r32 m32 +// SHRL cl r32 m32 +func SHRL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRL: bad operands") +} + +// SHRQ: Logical Shift Right. +// +// Forms: +// +// SHRQ 1 r64 +// SHRQ imm8 r64 +// SHRQ cl r64 +// SHRQ 1 m64 +// SHRQ imm8 m64 +// SHRQ cl m64 +// SHRQ imm8 r64 r64 +// SHRQ cl r64 r64 +// SHRQ imm8 r64 m64 +// SHRQ cl r64 m64 +func SHRQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRQ: bad operands") +} + +// SHRW: Logical Shift Right. +// +// Forms: +// +// SHRW 1 r16 +// SHRW imm8 r16 +// SHRW cl r16 +// SHRW 1 m16 +// SHRW imm8 m16 +// SHRW cl m16 +// SHRW imm8 r16 r16 +// SHRW cl r16 r16 +// SHRW imm8 r16 m16 +// SHRW cl r16 m16 +func SHRW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRW: bad operands") +} + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +func SHRXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHRXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHRXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SHRXL: bad operands") +} + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +func SHRXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHRXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHRXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + ISA: []string{"BMI2"}, + }, nil + } + return nil, errors.New("SHRXQ: bad operands") +} + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +func SHUFPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("SHUFPD: bad operands") +} + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +func SHUFPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("SHUFPS: bad operands") +} + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +func SQRTPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("SQRTPD: bad operands") +} + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +func SQRTPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("SQRTPS: bad operands") +} + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +func SQRTSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("SQRTSD: bad operands") +} + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +func SQRTSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("SQRTSS: bad operands") +} + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +func STC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "STC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +func STD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "STD", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +func STMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "STMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{m}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("STMXCSR: bad operands") +} + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +func SUBB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SUBB: bad operands") +} + +// SUBL: Subtract. +// +// Forms: +// +// SUBL imm32 eax +// SUBL imm8 r32 +// SUBL imm32 r32 +// SUBL r32 r32 +// SUBL m32 r32 +// SUBL imm8 m32 +// SUBL imm32 m32 +// SUBL r32 m32 +func SUBL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + CancellingInputs: true, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("SUBL: bad operands") +} + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +func SUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("SUBPD: bad operands") +} + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +func SUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("SUBPS: bad operands") +} + +// SUBQ: Subtract. +// +// Forms: +// +// SUBQ imm32 rax +// SUBQ imm8 r64 +// SUBQ imm32 r64 +// SUBQ r64 r64 +// SUBQ m64 r64 +// SUBQ imm8 m64 +// SUBQ imm32 m64 +// SUBQ r64 m64 +func SUBQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + CancellingInputs: true, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SUBQ: bad operands") +} + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +func SUBSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("SUBSD: bad operands") +} + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +func SUBSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("SUBSS: bad operands") +} + +// SUBW: Subtract. +// +// Forms: +// +// SUBW imm16 ax +// SUBW imm8 r16 +// SUBW imm16 r16 +// SUBW r16 r16 +// SUBW m16 r16 +// SUBW imm8 m16 +// SUBW imm16 m16 +// SUBW r16 m16 +func SUBW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SUBW: bad operands") +} + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +func SYSCALL() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "SYSCALL", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.R11, reg.RCX}, + }, nil +} + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +func TESTB(ir, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(ir) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(ir) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTB: bad operands") +} + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +func TESTL(ir, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(ir) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{ir, emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{ir, emr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTL: bad operands") +} + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +func TESTQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(ir) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTQ: bad operands") +} + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +func TESTW(ir, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(ir) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM16(ir) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM16(ir) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTW: bad operands") +} + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +func TZCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "TZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "TZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("TZCNTL: bad operands") +} + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +func TZCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "TZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "TZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("TZCNTQ: bad operands") +} + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +func TZCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "TZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "TZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + ISA: []string{"BMI"}, + }, nil + } + return nil, errors.New("TZCNTW: bad operands") +} + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +func UCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("UCOMISD: bad operands") +} + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +func UCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("UCOMISS: bad operands") +} + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +func UD2() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "UD2", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +func UNPCKHPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("UNPCKHPD: bad operands") +} + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +func UNPCKHPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("UNPCKHPS: bad operands") +} + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +func UNPCKLPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("UNPCKLPD: bad operands") +} + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +func UNPCKLPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("UNPCKLPS: bad operands") +} + +// VADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDPD xmm xmm xmm +// VADDPD m128 xmm xmm +// VADDPD ymm ymm ymm +// VADDPD m256 ymm ymm +func VADDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDPD: bad operands") +} + +// VADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDPS xmm xmm xmm +// VADDPS m128 xmm xmm +// VADDPS ymm ymm ymm +// VADDPS m256 ymm ymm +func VADDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDPS: bad operands") +} + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +func VADDSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDSD: bad operands") +} + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +func VADDSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDSS: bad operands") +} + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +func VADDSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDSUBPD: bad operands") +} + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +func VADDSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VADDSUBPS: bad operands") +} + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +func VAESDEC(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDEC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDEC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESDEC: bad operands") +} + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +func VAESDECLAST(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDECLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDECLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESDECLAST: bad operands") +} + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +func VAESENC(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESENC: bad operands") +} + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +func VAESENCLAST(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENCLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENCLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESENCLAST: bad operands") +} + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +func VAESIMC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESIMC: bad operands") +} + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +func VAESKEYGENASSIST(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX", "AES"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX", "AES"}, + }, nil + } + return nil, errors.New("VAESKEYGENASSIST: bad operands") +} + +// VANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPD xmm xmm xmm +// VANDNPD m128 xmm xmm +// VANDNPD ymm ymm ymm +// VANDNPD m256 ymm ymm +func VANDNPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VANDNPD: bad operands") +} + +// VANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPS xmm xmm xmm +// VANDNPS m128 xmm xmm +// VANDNPS ymm ymm ymm +// VANDNPS m256 ymm ymm +func VANDNPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VANDNPS: bad operands") +} + +// VANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDPD xmm xmm xmm +// VANDPD m128 xmm xmm +// VANDPD ymm ymm ymm +// VANDPD m256 ymm ymm +func VANDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VANDPD: bad operands") +} + +// VANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDPS xmm xmm xmm +// VANDPS m128 xmm xmm +// VANDPS ymm ymm ymm +// VANDPS m256 ymm ymm +func VANDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VANDPS: bad operands") +} + +// VBLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPD imm8 xmm xmm xmm +// VBLENDPD imm8 m128 xmm xmm +// VBLENDPD imm8 ymm ymm ymm +// VBLENDPD imm8 m256 ymm ymm +func VBLENDPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBLENDPD: bad operands") +} + +// VBLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPS imm8 xmm xmm xmm +// VBLENDPS imm8 m128 xmm xmm +// VBLENDPS imm8 ymm ymm ymm +// VBLENDPS imm8 m256 ymm ymm +func VBLENDPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBLENDPS: bad operands") +} + +// VBLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPD xmm xmm xmm xmm +// VBLENDVPD xmm m128 xmm xmm +// VBLENDVPD ymm ymm ymm ymm +// VBLENDVPD ymm m256 ymm ymm +func VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBLENDVPD: bad operands") +} + +// VBLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPS xmm xmm xmm xmm +// VBLENDVPS xmm m128 xmm xmm +// VBLENDVPS ymm ymm ymm ymm +// VBLENDVPS ymm m256 ymm ymm +func VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBLENDVPS: bad operands") +} + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +func VBROADCASTF128(m, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTF128", + Operands: []operand.Op{m, y}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBROADCASTF128: bad operands") +} + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +func VBROADCASTI128(m, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTI128", + Operands: []operand.Op{m, y}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VBROADCASTI128: bad operands") +} + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +func VBROADCASTSD(mx, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTSD", + Operands: []operand.Op{mx, y}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTSD", + Operands: []operand.Op{mx, y}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBROADCASTSD: bad operands") +} + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +func VBROADCASTSS(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VBROADCASTSS: bad operands") +} + +// VCMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPD imm8 xmm xmm xmm +// VCMPPD imm8 m128 xmm xmm +// VCMPPD imm8 ymm ymm ymm +// VCMPPD imm8 m256 ymm ymm +func VCMPPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCMPPD: bad operands") +} + +// VCMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPS imm8 xmm xmm xmm +// VCMPPS imm8 m128 xmm xmm +// VCMPPS imm8 ymm ymm ymm +// VCMPPS imm8 m256 ymm ymm +func VCMPPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCMPPS: bad operands") +} + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +func VCMPSD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCMPSD: bad operands") +} + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +func VCMPSS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCMPSS: bad operands") +} + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +func VCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCOMISD: bad operands") +} + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +func VCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCOMISS: bad operands") +} + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +func VCVTDQ2PD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTDQ2PD: bad operands") +} + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +func VCVTDQ2PS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTDQ2PS: bad operands") +} + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +func VCVTPD2DQX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPD2DQX: bad operands") +} + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +func VCVTPD2DQY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPD2DQY: bad operands") +} + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +func VCVTPD2PSX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPD2PSX: bad operands") +} + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +func VCVTPD2PSY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPD2PSY: bad operands") +} + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +func VCVTPH2PS(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"F16C"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"F16C"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"F16C"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"F16C"}, + }, nil + } + return nil, errors.New("VCVTPH2PS: bad operands") +} + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +func VCVTPS2DQ(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPS2DQ: bad operands") +} + +// VCVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTPS2PD xmm xmm +// VCVTPS2PD m64 xmm +// VCVTPS2PD xmm ymm +// VCVTPS2PD m128 ymm +func VCVTPS2PD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTPS2PD: bad operands") +} + +// VCVTPS2PH: Convert Single-Precision FP value to Half-Precision FP value. +// +// Forms: +// +// VCVTPS2PH imm8 xmm xmm +// VCVTPS2PH imm8 ymm xmm +// VCVTPS2PH imm8 xmm m64 +// VCVTPS2PH imm8 ymm m128 +func VCVTPS2PH(i, xy, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + ISA: []string{"F16C"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + ISA: []string{"F16C"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsM64(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + ISA: []string{"F16C"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + ISA: []string{"F16C"}, + }, nil + } + return nil, errors.New("VCVTPS2PH: bad operands") +} + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +func VCVTSD2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSD2SI: bad operands") +} + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +func VCVTSD2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSD2SIQ: bad operands") +} + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +func VCVTSD2SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSD2SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSD2SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSD2SS: bad operands") +} + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +func VCVTSI2SDL(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSI2SDL: bad operands") +} + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +func VCVTSI2SDQ(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSI2SDQ: bad operands") +} + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +func VCVTSI2SSL(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSI2SSL: bad operands") +} + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +func VCVTSI2SSQ(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSI2SSQ: bad operands") +} + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +func VCVTSS2SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSS2SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSS2SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSS2SD: bad operands") +} + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +func VCVTSS2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSS2SI: bad operands") +} + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +func VCVTSS2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTSS2SIQ: bad operands") +} + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +func VCVTTPD2DQX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTPD2DQX: bad operands") +} + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +func VCVTTPD2DQY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTPD2DQY: bad operands") +} + +// VCVTTPS2DQ: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPS2DQ xmm xmm +// VCVTTPS2DQ m128 xmm +// VCVTTPS2DQ ymm ymm +// VCVTTPS2DQ m256 ymm +func VCVTTPS2DQ(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTPS2DQ: bad operands") +} + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +func VCVTTSD2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTSD2SI: bad operands") +} + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +func VCVTTSD2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTSD2SIQ: bad operands") +} + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +func VCVTTSS2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTSS2SI: bad operands") +} + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +func VCVTTSS2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VCVTTSS2SIQ: bad operands") +} + +// VDIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPD xmm xmm xmm +// VDIVPD m128 xmm xmm +// VDIVPD ymm ymm ymm +// VDIVPD m256 ymm ymm +func VDIVPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDIVPD: bad operands") +} + +// VDIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPS xmm xmm xmm +// VDIVPS m128 xmm xmm +// VDIVPS ymm ymm ymm +// VDIVPS m256 ymm ymm +func VDIVPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDIVPS: bad operands") +} + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +func VDIVSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDIVSD: bad operands") +} + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +func VDIVSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDIVSS: bad operands") +} + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +func VDPPD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDPPD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDPPD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDPPD: bad operands") +} + +// VDPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VDPPS imm8 xmm xmm xmm +// VDPPS imm8 m128 xmm xmm +// VDPPS imm8 ymm ymm ymm +// VDPPS imm8 m256 ymm ymm +func VDPPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VDPPS: bad operands") +} + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +func VEXTRACTF128(i, y, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTF128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTF128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VEXTRACTF128: bad operands") +} + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +func VEXTRACTI128(i, y, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTI128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTI128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VEXTRACTI128: bad operands") +} + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +func VEXTRACTPS(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VEXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "VEXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VEXTRACTPS: bad operands") +} + +// VFMADD132PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PD xmm xmm xmm +// VFMADD132PD m128 xmm xmm +// VFMADD132PD ymm ymm ymm +// VFMADD132PD m256 ymm ymm +func VFMADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD132PD: bad operands") +} + +// VFMADD132PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PS xmm xmm xmm +// VFMADD132PS m128 xmm xmm +// VFMADD132PS ymm ymm ymm +// VFMADD132PS m256 ymm ymm +func VFMADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD132PS: bad operands") +} + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +func VFMADD132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD132SD: bad operands") +} + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +func VFMADD132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD132SS: bad operands") +} + +// VFMADD213PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PD xmm xmm xmm +// VFMADD213PD m128 xmm xmm +// VFMADD213PD ymm ymm ymm +// VFMADD213PD m256 ymm ymm +func VFMADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD213PD: bad operands") +} + +// VFMADD213PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PS xmm xmm xmm +// VFMADD213PS m128 xmm xmm +// VFMADD213PS ymm ymm ymm +// VFMADD213PS m256 ymm ymm +func VFMADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD213PS: bad operands") +} + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +func VFMADD213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD213SD: bad operands") +} + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +func VFMADD213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD213SS: bad operands") +} + +// VFMADD231PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PD xmm xmm xmm +// VFMADD231PD m128 xmm xmm +// VFMADD231PD ymm ymm ymm +// VFMADD231PD m256 ymm ymm +func VFMADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD231PD: bad operands") +} + +// VFMADD231PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PS xmm xmm xmm +// VFMADD231PS m128 xmm xmm +// VFMADD231PS ymm ymm ymm +// VFMADD231PS m256 ymm ymm +func VFMADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD231PS: bad operands") +} + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +func VFMADD231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD231SD: bad operands") +} + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +func VFMADD231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADD231SS: bad operands") +} + +// VFMADDSUB132PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PD xmm xmm xmm +// VFMADDSUB132PD m128 xmm xmm +// VFMADDSUB132PD ymm ymm ymm +// VFMADDSUB132PD m256 ymm ymm +func VFMADDSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB132PD: bad operands") +} + +// VFMADDSUB132PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PS xmm xmm xmm +// VFMADDSUB132PS m128 xmm xmm +// VFMADDSUB132PS ymm ymm ymm +// VFMADDSUB132PS m256 ymm ymm +func VFMADDSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB132PS: bad operands") +} + +// VFMADDSUB213PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PD xmm xmm xmm +// VFMADDSUB213PD m128 xmm xmm +// VFMADDSUB213PD ymm ymm ymm +// VFMADDSUB213PD m256 ymm ymm +func VFMADDSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB213PD: bad operands") +} + +// VFMADDSUB213PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PS xmm xmm xmm +// VFMADDSUB213PS m128 xmm xmm +// VFMADDSUB213PS ymm ymm ymm +// VFMADDSUB213PS m256 ymm ymm +func VFMADDSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB213PS: bad operands") +} + +// VFMADDSUB231PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PD xmm xmm xmm +// VFMADDSUB231PD m128 xmm xmm +// VFMADDSUB231PD ymm ymm ymm +// VFMADDSUB231PD m256 ymm ymm +func VFMADDSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB231PD: bad operands") +} + +// VFMADDSUB231PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PS xmm xmm xmm +// VFMADDSUB231PS m128 xmm xmm +// VFMADDSUB231PS ymm ymm ymm +// VFMADDSUB231PS m256 ymm ymm +func VFMADDSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMADDSUB231PS: bad operands") +} + +// VFMSUB132PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PD xmm xmm xmm +// VFMSUB132PD m128 xmm xmm +// VFMSUB132PD ymm ymm ymm +// VFMSUB132PD m256 ymm ymm +func VFMSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB132PD: bad operands") +} + +// VFMSUB132PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PS xmm xmm xmm +// VFMSUB132PS m128 xmm xmm +// VFMSUB132PS ymm ymm ymm +// VFMSUB132PS m256 ymm ymm +func VFMSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB132PS: bad operands") +} + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +func VFMSUB132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB132SD: bad operands") +} + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +func VFMSUB132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB132SS: bad operands") +} + +// VFMSUB213PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PD xmm xmm xmm +// VFMSUB213PD m128 xmm xmm +// VFMSUB213PD ymm ymm ymm +// VFMSUB213PD m256 ymm ymm +func VFMSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB213PD: bad operands") +} + +// VFMSUB213PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PS xmm xmm xmm +// VFMSUB213PS m128 xmm xmm +// VFMSUB213PS ymm ymm ymm +// VFMSUB213PS m256 ymm ymm +func VFMSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB213PS: bad operands") +} + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +func VFMSUB213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB213SD: bad operands") +} + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +func VFMSUB213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB213SS: bad operands") +} + +// VFMSUB231PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PD xmm xmm xmm +// VFMSUB231PD m128 xmm xmm +// VFMSUB231PD ymm ymm ymm +// VFMSUB231PD m256 ymm ymm +func VFMSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB231PD: bad operands") +} + +// VFMSUB231PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PS xmm xmm xmm +// VFMSUB231PS m128 xmm xmm +// VFMSUB231PS ymm ymm ymm +// VFMSUB231PS m256 ymm ymm +func VFMSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB231PS: bad operands") +} + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +func VFMSUB231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB231SD: bad operands") +} + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +func VFMSUB231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUB231SS: bad operands") +} + +// VFMSUBADD132PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PD xmm xmm xmm +// VFMSUBADD132PD m128 xmm xmm +// VFMSUBADD132PD ymm ymm ymm +// VFMSUBADD132PD m256 ymm ymm +func VFMSUBADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD132PD: bad operands") +} + +// VFMSUBADD132PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PS xmm xmm xmm +// VFMSUBADD132PS m128 xmm xmm +// VFMSUBADD132PS ymm ymm ymm +// VFMSUBADD132PS m256 ymm ymm +func VFMSUBADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD132PS: bad operands") +} + +// VFMSUBADD213PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PD xmm xmm xmm +// VFMSUBADD213PD m128 xmm xmm +// VFMSUBADD213PD ymm ymm ymm +// VFMSUBADD213PD m256 ymm ymm +func VFMSUBADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD213PD: bad operands") +} + +// VFMSUBADD213PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PS xmm xmm xmm +// VFMSUBADD213PS m128 xmm xmm +// VFMSUBADD213PS ymm ymm ymm +// VFMSUBADD213PS m256 ymm ymm +func VFMSUBADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD213PS: bad operands") +} + +// VFMSUBADD231PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PD xmm xmm xmm +// VFMSUBADD231PD m128 xmm xmm +// VFMSUBADD231PD ymm ymm ymm +// VFMSUBADD231PD m256 ymm ymm +func VFMSUBADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD231PD: bad operands") +} + +// VFMSUBADD231PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PS xmm xmm xmm +// VFMSUBADD231PS m128 xmm xmm +// VFMSUBADD231PS ymm ymm ymm +// VFMSUBADD231PS m256 ymm ymm +func VFMSUBADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFMSUBADD231PS: bad operands") +} + +// VFNMADD132PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PD xmm xmm xmm +// VFNMADD132PD m128 xmm xmm +// VFNMADD132PD ymm ymm ymm +// VFNMADD132PD m256 ymm ymm +func VFNMADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD132PD: bad operands") +} + +// VFNMADD132PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PS xmm xmm xmm +// VFNMADD132PS m128 xmm xmm +// VFNMADD132PS ymm ymm ymm +// VFNMADD132PS m256 ymm ymm +func VFNMADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD132PS: bad operands") +} + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +func VFNMADD132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD132SD: bad operands") +} + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +func VFNMADD132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD132SS: bad operands") +} + +// VFNMADD213PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PD xmm xmm xmm +// VFNMADD213PD m128 xmm xmm +// VFNMADD213PD ymm ymm ymm +// VFNMADD213PD m256 ymm ymm +func VFNMADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD213PD: bad operands") +} + +// VFNMADD213PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PS xmm xmm xmm +// VFNMADD213PS m128 xmm xmm +// VFNMADD213PS ymm ymm ymm +// VFNMADD213PS m256 ymm ymm +func VFNMADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD213PS: bad operands") +} + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +func VFNMADD213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD213SD: bad operands") +} + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +func VFNMADD213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD213SS: bad operands") +} + +// VFNMADD231PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PD xmm xmm xmm +// VFNMADD231PD m128 xmm xmm +// VFNMADD231PD ymm ymm ymm +// VFNMADD231PD m256 ymm ymm +func VFNMADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD231PD: bad operands") +} + +// VFNMADD231PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PS xmm xmm xmm +// VFNMADD231PS m128 xmm xmm +// VFNMADD231PS ymm ymm ymm +// VFNMADD231PS m256 ymm ymm +func VFNMADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD231PS: bad operands") +} + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +func VFNMADD231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD231SD: bad operands") +} + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +func VFNMADD231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMADD231SS: bad operands") +} + +// VFNMSUB132PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PD xmm xmm xmm +// VFNMSUB132PD m128 xmm xmm +// VFNMSUB132PD ymm ymm ymm +// VFNMSUB132PD m256 ymm ymm +func VFNMSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB132PD: bad operands") +} + +// VFNMSUB132PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PS xmm xmm xmm +// VFNMSUB132PS m128 xmm xmm +// VFNMSUB132PS ymm ymm ymm +// VFNMSUB132PS m256 ymm ymm +func VFNMSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB132PS: bad operands") +} + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +func VFNMSUB132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB132SD: bad operands") +} + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +func VFNMSUB132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB132SS: bad operands") +} + +// VFNMSUB213PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PD xmm xmm xmm +// VFNMSUB213PD m128 xmm xmm +// VFNMSUB213PD ymm ymm ymm +// VFNMSUB213PD m256 ymm ymm +func VFNMSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB213PD: bad operands") +} + +// VFNMSUB213PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PS xmm xmm xmm +// VFNMSUB213PS m128 xmm xmm +// VFNMSUB213PS ymm ymm ymm +// VFNMSUB213PS m256 ymm ymm +func VFNMSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB213PS: bad operands") +} + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +func VFNMSUB213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB213SD: bad operands") +} + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +func VFNMSUB213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB213SS: bad operands") +} + +// VFNMSUB231PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PD xmm xmm xmm +// VFNMSUB231PD m128 xmm xmm +// VFNMSUB231PD ymm ymm ymm +// VFNMSUB231PD m256 ymm ymm +func VFNMSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB231PD: bad operands") +} + +// VFNMSUB231PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PS xmm xmm xmm +// VFNMSUB231PS m128 xmm xmm +// VFNMSUB231PS ymm ymm ymm +// VFNMSUB231PS m256 ymm ymm +func VFNMSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB231PS: bad operands") +} + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +func VFNMSUB231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB231SD: bad operands") +} + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +func VFNMSUB231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + ISA: []string{"FMA3"}, + }, nil + } + return nil, errors.New("VFNMSUB231SS: bad operands") +} + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +func VGATHERDPD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32X(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VGATHERDPD: bad operands") +} + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +func VGATHERDPS(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPS", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPS", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VGATHERDPS: bad operands") +} + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +func VGATHERQPD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM64X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERQPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM64Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERQPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VGATHERQPD: bad operands") +} + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +func VGATHERQPS(x, v, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsVM64X(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VGATHERQPS", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(x) && operand.IsVM64Y(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VGATHERQPS", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VGATHERQPS: bad operands") +} + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +func VHADDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VHADDPD: bad operands") +} + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +func VHADDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VHADDPS: bad operands") +} + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +func VHSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VHSUBPD: bad operands") +} + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +func VHSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VHSUBPS: bad operands") +} + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +func VINSERTF128(i, mx, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTF128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTF128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VINSERTF128: bad operands") +} + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +func VINSERTI128(i, mx, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTI128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTI128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VINSERTI128: bad operands") +} + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +func VINSERTPS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VINSERTPS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VINSERTPS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VINSERTPS: bad operands") +} + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +func VLDDQU(m, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VLDDQU", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(m) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VLDDQU", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VLDDQU: bad operands") +} + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +func VLDMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "VLDMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VLDMXCSR: bad operands") +} + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +func VMASKMOVDQU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMASKMOVDQU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMASKMOVDQU: bad operands") +} + +// VMASKMOVPD: Conditional Move Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPD m128 xmm xmm +// VMASKMOVPD m256 ymm ymm +// VMASKMOVPD xmm xmm m128 +// VMASKMOVPD ymm ymm m256 +func VMASKMOVPD(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMASKMOVPD: bad operands") +} + +// VMASKMOVPS: Conditional Move Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPS m128 xmm xmm +// VMASKMOVPS m256 ymm ymm +// VMASKMOVPS xmm xmm m128 +// VMASKMOVPS ymm ymm m256 +func VMASKMOVPS(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMASKMOVPS: bad operands") +} + +// VMAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPD xmm xmm xmm +// VMAXPD m128 xmm xmm +// VMAXPD ymm ymm ymm +// VMAXPD m256 ymm ymm +func VMAXPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMAXPD: bad operands") +} + +// VMAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPS xmm xmm xmm +// VMAXPS m128 xmm xmm +// VMAXPS ymm ymm ymm +// VMAXPS m256 ymm ymm +func VMAXPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMAXPS: bad operands") +} + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +func VMAXSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMAXSD: bad operands") +} + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +func VMAXSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMAXSS: bad operands") +} + +// VMINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMINPD xmm xmm xmm +// VMINPD m128 xmm xmm +// VMINPD ymm ymm ymm +// VMINPD m256 ymm ymm +func VMINPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMINPD: bad operands") +} + +// VMINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMINPS xmm xmm xmm +// VMINPS m128 xmm xmm +// VMINPS ymm ymm ymm +// VMINPS m256 ymm ymm +func VMINPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMINPS: bad operands") +} + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +func VMINSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMINSD: bad operands") +} + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +func VMINSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMINSS: bad operands") +} + +// VMOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPD xmm xmm +// VMOVAPD m128 xmm +// VMOVAPD ymm ymm +// VMOVAPD m256 ymm +// VMOVAPD xmm m128 +// VMOVAPD ymm m256 +func VMOVAPD(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVAPD: bad operands") +} + +// VMOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPS xmm xmm +// VMOVAPS m128 xmm +// VMOVAPS ymm ymm +// VMOVAPS m256 ymm +// VMOVAPS xmm m128 +// VMOVAPS ymm m256 +func VMOVAPS(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVAPS: bad operands") +} + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +func VMOVD(mrx, mrx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mrx) && operand.IsR32(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsR32(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mrx) && operand.IsM32(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVD: bad operands") +} + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +func VMOVDDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVDDUP: bad operands") +} + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +func VMOVDQA(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVDQA: bad operands") +} + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +func VMOVDQU(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVDQU: bad operands") +} + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +func VMOVHLPS(x, x1, x2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1) && operand.IsXMM(x2): + return &intrep.Instruction{ + Opcode: "VMOVHLPS", + Operands: []operand.Op{x, x1, x2}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x2}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVHLPS: bad operands") +} + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +func VMOVHPD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVHPD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVHPD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVHPD: bad operands") +} + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +func VMOVHPS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVHPS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVHPS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVHPS: bad operands") +} + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +func VMOVLHPS(x, x1, x2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1) && operand.IsXMM(x2): + return &intrep.Instruction{ + Opcode: "VMOVLHPS", + Operands: []operand.Op{x, x1, x2}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x2}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVLHPS: bad operands") +} + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +func VMOVLPD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVLPD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVLPD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVLPD: bad operands") +} + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +func VMOVLPS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVLPS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVLPS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVLPS: bad operands") +} + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +func VMOVMSKPD(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPD", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPD", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVMSKPD: bad operands") +} + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +func VMOVMSKPS(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPS", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPS", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVMSKPS: bad operands") +} + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +func VMOVNTDQ(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTDQ", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTDQ", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVNTDQ: bad operands") +} + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +func VMOVNTDQA(m, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVNTDQA", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(m) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVNTDQA", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VMOVNTDQA: bad operands") +} + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +func VMOVNTPD(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPD", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPD", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVNTPD: bad operands") +} + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +func VMOVNTPS(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPS", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPS", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVNTPS: bad operands") +} + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +func VMOVQ(mrx, mrx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mrx) && operand.IsR64(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsR64(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mrx) && operand.IsM64(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVQ: bad operands") +} + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +func VMOVSD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsXMM(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVSD: bad operands") +} + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +func VMOVSHDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVSHDUP: bad operands") +} + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +func VMOVSLDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVSLDUP: bad operands") +} + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +func VMOVSS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsM32(ops[0]) && operand.IsXMM(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + ISA: []string{"AVX"}, + }, nil + case len(ops) == 3 && operand.IsXMM(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVSS: bad operands") +} + +// VMOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPD xmm xmm +// VMOVUPD m128 xmm +// VMOVUPD ymm ymm +// VMOVUPD m256 ymm +// VMOVUPD xmm m128 +// VMOVUPD ymm m256 +func VMOVUPD(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVUPD: bad operands") +} + +// VMOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPS xmm xmm +// VMOVUPS m128 xmm +// VMOVUPS ymm ymm +// VMOVUPS m256 ymm +// VMOVUPS xmm m128 +// VMOVUPS ymm m256 +func VMOVUPS(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMOVUPS: bad operands") +} + +// VMPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// VMPSADBW imm8 xmm xmm xmm +// VMPSADBW imm8 m128 xmm xmm +// VMPSADBW imm8 ymm ymm ymm +// VMPSADBW imm8 m256 ymm ymm +func VMPSADBW(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VMPSADBW: bad operands") +} + +// VMULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULPD xmm xmm xmm +// VMULPD m128 xmm xmm +// VMULPD ymm ymm ymm +// VMULPD m256 ymm ymm +func VMULPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMULPD: bad operands") +} + +// VMULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULPS xmm xmm xmm +// VMULPS m128 xmm xmm +// VMULPS ymm ymm ymm +// VMULPS m256 ymm ymm +func VMULPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMULPS: bad operands") +} + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +func VMULSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMULSD: bad operands") +} + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +func VMULSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VMULSS: bad operands") +} + +// VORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// VORPD xmm xmm xmm +// VORPD m128 xmm xmm +// VORPD ymm ymm ymm +// VORPD m256 ymm ymm +func VORPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VORPD: bad operands") +} + +// VORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// VORPS xmm xmm xmm +// VORPS m128 xmm xmm +// VORPS ymm ymm ymm +// VORPS m256 ymm ymm +func VORPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VORPS: bad operands") +} + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +func VPABSB(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPABSB: bad operands") +} + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +func VPABSD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPABSD: bad operands") +} + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +func VPABSW(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPABSW: bad operands") +} + +// VPACKSSDW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// VPACKSSDW xmm xmm xmm +// VPACKSSDW m128 xmm xmm +// VPACKSSDW ymm ymm ymm +// VPACKSSDW m256 ymm ymm +func VPACKSSDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPACKSSDW: bad operands") +} + +// VPACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// VPACKSSWB xmm xmm xmm +// VPACKSSWB m128 xmm xmm +// VPACKSSWB ymm ymm ymm +// VPACKSSWB m256 ymm ymm +func VPACKSSWB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPACKSSWB: bad operands") +} + +// VPACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// VPACKUSDW xmm xmm xmm +// VPACKUSDW m128 xmm xmm +// VPACKUSDW ymm ymm ymm +// VPACKUSDW m256 ymm ymm +func VPACKUSDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPACKUSDW: bad operands") +} + +// VPACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// VPACKUSWB xmm xmm xmm +// VPACKUSWB m128 xmm xmm +// VPACKUSWB ymm ymm ymm +// VPACKUSWB m256 ymm ymm +func VPACKUSWB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPACKUSWB: bad operands") +} + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +func VPADDB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDB: bad operands") +} + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +func VPADDD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDD: bad operands") +} + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +func VPADDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDQ: bad operands") +} + +// VPADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPADDSB xmm xmm xmm +// VPADDSB m128 xmm xmm +// VPADDSB ymm ymm ymm +// VPADDSB m256 ymm ymm +func VPADDSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDSB: bad operands") +} + +// VPADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPADDSW xmm xmm xmm +// VPADDSW m128 xmm xmm +// VPADDSW ymm ymm ymm +// VPADDSW m256 ymm ymm +func VPADDSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDSW: bad operands") +} + +// VPADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSB xmm xmm xmm +// VPADDUSB m128 xmm xmm +// VPADDUSB ymm ymm ymm +// VPADDUSB m256 ymm ymm +func VPADDUSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDUSB: bad operands") +} + +// VPADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSW xmm xmm xmm +// VPADDUSW m128 xmm xmm +// VPADDUSW ymm ymm ymm +// VPADDUSW m256 ymm ymm +func VPADDUSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDUSW: bad operands") +} + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +func VPADDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPADDW: bad operands") +} + +// VPALIGNR: Packed Align Right. +// +// Forms: +// +// VPALIGNR imm8 xmm xmm xmm +// VPALIGNR imm8 m128 xmm xmm +// VPALIGNR imm8 ymm ymm ymm +// VPALIGNR imm8 m256 ymm ymm +func VPALIGNR(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPALIGNR: bad operands") +} + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +func VPAND(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPAND: bad operands") +} + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +func VPANDN(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPANDN: bad operands") +} + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +func VPAVGB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPAVGB: bad operands") +} + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +func VPAVGW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPAVGW: bad operands") +} + +// VPBLENDD: Blend Packed Doublewords. +// +// Forms: +// +// VPBLENDD imm8 xmm xmm xmm +// VPBLENDD imm8 m128 xmm xmm +// VPBLENDD imm8 ymm ymm ymm +// VPBLENDD imm8 m256 ymm ymm +func VPBLENDD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBLENDD: bad operands") +} + +// VPBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// VPBLENDVB xmm xmm xmm xmm +// VPBLENDVB xmm m128 xmm xmm +// VPBLENDVB ymm ymm ymm ymm +// VPBLENDVB ymm m256 ymm ymm +func VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBLENDVB: bad operands") +} + +// VPBLENDW: Blend Packed Words. +// +// Forms: +// +// VPBLENDW imm8 xmm xmm xmm +// VPBLENDW imm8 m128 xmm xmm +// VPBLENDW imm8 ymm ymm ymm +// VPBLENDW imm8 m256 ymm ymm +func VPBLENDW(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBLENDW: bad operands") +} + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +func VPBROADCASTB(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM8(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM8(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBROADCASTB: bad operands") +} + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +func VPBROADCASTD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBROADCASTD: bad operands") +} + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +func VPBROADCASTQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBROADCASTQ: bad operands") +} + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +func VPBROADCASTW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM16(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPBROADCASTW: bad operands") +} + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +func VPCLMULQDQ(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPCLMULQDQ", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "PCLMULQDQ"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPCLMULQDQ", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX", "PCLMULQDQ"}, + }, nil + } + return nil, errors.New("VPCLMULQDQ: bad operands") +} + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +func VPCMPEQB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPEQB: bad operands") +} + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +func VPCMPEQD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPEQD: bad operands") +} + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +func VPCMPEQQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPEQQ: bad operands") +} + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +func VPCMPEQW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPEQW: bad operands") +} + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +func VPCMPESTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPCMPESTRI: bad operands") +} + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +func VPCMPESTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPCMPESTRM: bad operands") +} + +// VPCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// VPCMPGTB xmm xmm xmm +// VPCMPGTB m128 xmm xmm +// VPCMPGTB ymm ymm ymm +// VPCMPGTB m256 ymm ymm +func VPCMPGTB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPGTB: bad operands") +} + +// VPCMPGTD: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// VPCMPGTD xmm xmm xmm +// VPCMPGTD m128 xmm xmm +// VPCMPGTD ymm ymm ymm +// VPCMPGTD m256 ymm ymm +func VPCMPGTD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPGTD: bad operands") +} + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +func VPCMPGTQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPGTQ: bad operands") +} + +// VPCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// VPCMPGTW xmm xmm xmm +// VPCMPGTW m128 xmm xmm +// VPCMPGTW ymm ymm ymm +// VPCMPGTW m256 ymm ymm +func VPCMPGTW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPCMPGTW: bad operands") +} + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +func VPCMPISTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPCMPISTRI: bad operands") +} + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +func VPCMPISTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPCMPISTRM: bad operands") +} + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +func VPERM2F128(i, my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2F128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2F128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPERM2F128: bad operands") +} + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +func VPERM2I128(i, my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2I128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2I128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPERM2I128: bad operands") +} + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +func VPERMD(my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMD", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMD", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPERMD: bad operands") +} + +// VPERMILPD: Permute Double-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPD imm8 xmm xmm +// VPERMILPD xmm xmm xmm +// VPERMILPD m128 xmm xmm +// VPERMILPD imm8 m128 xmm +// VPERMILPD imm8 ymm ymm +// VPERMILPD ymm ymm ymm +// VPERMILPD m256 ymm ymm +// VPERMILPD imm8 m256 ymm +func VPERMILPD(imxy, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPERMILPD: bad operands") +} + +// VPERMILPS: Permute Single-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPS imm8 xmm xmm +// VPERMILPS xmm xmm xmm +// VPERMILPS m128 xmm xmm +// VPERMILPS imm8 m128 xmm +// VPERMILPS imm8 ymm ymm +// VPERMILPS ymm ymm ymm +// VPERMILPS m256 ymm ymm +// VPERMILPS imm8 m256 ymm +func VPERMILPS(imxy, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPERMILPS: bad operands") +} + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +func VPERMPD(i, my, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMPD", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMPD", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPERMPD: bad operands") +} + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +func VPERMPS(my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMPS", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMPS", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPERMPS: bad operands") +} + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +func VPERMQ(i, my, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMQ", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMQ", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPERMQ: bad operands") +} + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +func VPEXTRB(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPEXTRB: bad operands") +} + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +func VPEXTRD(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPEXTRD: bad operands") +} + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +func VPEXTRQ(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPEXTRQ: bad operands") +} + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +func VPEXTRW(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPEXTRW: bad operands") +} + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +func VPGATHERDD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPGATHERDD: bad operands") +} + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +func VPGATHERDQ(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32X(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPGATHERDQ: bad operands") +} + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +func VPGATHERQD(x, v, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsVM64X(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPGATHERQD", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(x) && operand.IsVM64Y(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPGATHERQD", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPGATHERQD: bad operands") +} + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +func VPGATHERQQ(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM64X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERQQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(xy) && operand.IsVM64Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERQQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPGATHERQQ: bad operands") +} + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +func VPHADDD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHADDD: bad operands") +} + +// VPHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHADDSW xmm xmm xmm +// VPHADDSW m128 xmm xmm +// VPHADDSW ymm ymm ymm +// VPHADDSW m256 ymm ymm +func VPHADDSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHADDSW: bad operands") +} + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +func VPHADDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHADDW: bad operands") +} + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +func VPHMINPOSUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPHMINPOSUW: bad operands") +} + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +func VPHSUBD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHSUBD: bad operands") +} + +// VPHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHSUBSW xmm xmm xmm +// VPHSUBSW m128 xmm xmm +// VPHSUBSW ymm ymm ymm +// VPHSUBSW m256 ymm ymm +func VPHSUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHSUBSW: bad operands") +} + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +func VPHSUBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPHSUBW: bad operands") +} + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +func VPINSRB(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRB", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM8(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRB", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPINSRB: bad operands") +} + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +func VPINSRD(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRD", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRD", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPINSRD: bad operands") +} + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +func VPINSRQ(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRQ", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRQ", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPINSRQ: bad operands") +} + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +func VPINSRW(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRW", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRW", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPINSRW: bad operands") +} + +// VPMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// VPMADDUBSW xmm xmm xmm +// VPMADDUBSW m128 xmm xmm +// VPMADDUBSW ymm ymm ymm +// VPMADDUBSW m256 ymm ymm +func VPMADDUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMADDUBSW: bad operands") +} + +// VPMADDWD: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// VPMADDWD xmm xmm xmm +// VPMADDWD m128 xmm xmm +// VPMADDWD ymm ymm ymm +// VPMADDWD m256 ymm ymm +func VPMADDWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMADDWD: bad operands") +} + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +func VPMASKMOVD(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMASKMOVD: bad operands") +} + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +func VPMASKMOVQ(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMASKMOVQ: bad operands") +} + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +func VPMAXSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXSB: bad operands") +} + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +func VPMAXSD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXSD: bad operands") +} + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +func VPMAXSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXSW: bad operands") +} + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +func VPMAXUB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXUB: bad operands") +} + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +func VPMAXUD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXUD: bad operands") +} + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +func VPMAXUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMAXUW: bad operands") +} + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +func VPMINSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINSB: bad operands") +} + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +func VPMINSD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINSD: bad operands") +} + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +func VPMINSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINSW: bad operands") +} + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +func VPMINUB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINUB: bad operands") +} + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +func VPMINUD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINUD: bad operands") +} + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +func VPMINUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMINUW: bad operands") +} + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +func VPMOVMSKB(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VPMOVMSKB", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VPMOVMSKB", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVMSKB: bad operands") +} + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +func VPMOVSXBD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXBD: bad operands") +} + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +func VPMOVSXBQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXBQ: bad operands") +} + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +func VPMOVSXBW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXBW: bad operands") +} + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +func VPMOVSXDQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXDQ: bad operands") +} + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +func VPMOVSXWD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXWD: bad operands") +} + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +func VPMOVSXWQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVSXWQ: bad operands") +} + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +func VPMOVZXBD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXBD: bad operands") +} + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +func VPMOVZXBQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXBQ: bad operands") +} + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +func VPMOVZXBW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXBW: bad operands") +} + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +func VPMOVZXDQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXDQ: bad operands") +} + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +func VPMOVZXWD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXWD: bad operands") +} + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +func VPMOVZXWQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMOVZXWQ: bad operands") +} + +// VPMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// VPMULDQ xmm xmm xmm +// VPMULDQ m128 xmm xmm +// VPMULDQ ymm ymm ymm +// VPMULDQ m256 ymm ymm +func VPMULDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULDQ: bad operands") +} + +// VPMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// VPMULHRSW xmm xmm xmm +// VPMULHRSW m128 xmm xmm +// VPMULHRSW ymm ymm ymm +// VPMULHRSW m256 ymm ymm +func VPMULHRSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULHRSW: bad operands") +} + +// VPMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// VPMULHUW xmm xmm xmm +// VPMULHUW m128 xmm xmm +// VPMULHUW ymm ymm ymm +// VPMULHUW m256 ymm ymm +func VPMULHUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULHUW: bad operands") +} + +// VPMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// VPMULHW xmm xmm xmm +// VPMULHW m128 xmm xmm +// VPMULHW ymm ymm ymm +// VPMULHW m256 ymm ymm +func VPMULHW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULHW: bad operands") +} + +// VPMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// VPMULLD xmm xmm xmm +// VPMULLD m128 xmm xmm +// VPMULLD ymm ymm ymm +// VPMULLD m256 ymm ymm +func VPMULLD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULLD: bad operands") +} + +// VPMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// VPMULLW xmm xmm xmm +// VPMULLW m128 xmm xmm +// VPMULLW ymm ymm ymm +// VPMULLW m256 ymm ymm +func VPMULLW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULLW: bad operands") +} + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +func VPMULUDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPMULUDQ: bad operands") +} + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +func VPOR(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPOR: bad operands") +} + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +func VPSADBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSADBW: bad operands") +} + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +func VPSHUFB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSHUFB: bad operands") +} + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +func VPSHUFD(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSHUFD: bad operands") +} + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +func VPSHUFHW(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSHUFHW: bad operands") +} + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +func VPSHUFLW(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSHUFLW: bad operands") +} + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +func VPSIGNB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSIGNB: bad operands") +} + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +func VPSIGND(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSIGND: bad operands") +} + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +func VPSIGNW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSIGNW: bad operands") +} + +// VPSLLD: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLD imm8 xmm xmm +// VPSLLD xmm xmm xmm +// VPSLLD m128 xmm xmm +// VPSLLD imm8 ymm ymm +// VPSLLD xmm ymm ymm +// VPSLLD m128 ymm ymm +func VPSLLD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLD: bad operands") +} + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +func VPSLLDQ(i, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLDQ: bad operands") +} + +// VPSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLQ imm8 xmm xmm +// VPSLLQ xmm xmm xmm +// VPSLLQ m128 xmm xmm +// VPSLLQ imm8 ymm ymm +// VPSLLQ xmm ymm ymm +// VPSLLQ m128 ymm ymm +func VPSLLQ(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLQ: bad operands") +} + +// VPSLLVD: Variable Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLVD xmm xmm xmm +// VPSLLVD m128 xmm xmm +// VPSLLVD ymm ymm ymm +// VPSLLVD m256 ymm ymm +func VPSLLVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLVD: bad operands") +} + +// VPSLLVQ: Variable Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLVQ xmm xmm xmm +// VPSLLVQ m128 xmm xmm +// VPSLLVQ ymm ymm ymm +// VPSLLVQ m256 ymm ymm +func VPSLLVQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLVQ: bad operands") +} + +// VPSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// VPSLLW imm8 xmm xmm +// VPSLLW xmm xmm xmm +// VPSLLW m128 xmm xmm +// VPSLLW imm8 ymm ymm +// VPSLLW xmm ymm ymm +// VPSLLW m128 ymm ymm +func VPSLLW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSLLW: bad operands") +} + +// VPSRAD: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAD imm8 xmm xmm +// VPSRAD xmm xmm xmm +// VPSRAD m128 xmm xmm +// VPSRAD imm8 ymm ymm +// VPSRAD xmm ymm ymm +// VPSRAD m128 ymm ymm +func VPSRAD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRAD: bad operands") +} + +// VPSRAVD: Variable Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAVD xmm xmm xmm +// VPSRAVD m128 xmm xmm +// VPSRAVD ymm ymm ymm +// VPSRAVD m256 ymm ymm +func VPSRAVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRAVD: bad operands") +} + +// VPSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// VPSRAW imm8 xmm xmm +// VPSRAW xmm xmm xmm +// VPSRAW m128 xmm xmm +// VPSRAW imm8 ymm ymm +// VPSRAW xmm ymm ymm +// VPSRAW m128 ymm ymm +func VPSRAW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRAW: bad operands") +} + +// VPSRLD: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLD imm8 xmm xmm +// VPSRLD xmm xmm xmm +// VPSRLD m128 xmm xmm +// VPSRLD imm8 ymm ymm +// VPSRLD xmm ymm ymm +// VPSRLD m128 ymm ymm +func VPSRLD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLD: bad operands") +} + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +func VPSRLDQ(i, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLDQ: bad operands") +} + +// VPSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLQ imm8 xmm xmm +// VPSRLQ xmm xmm xmm +// VPSRLQ m128 xmm xmm +// VPSRLQ imm8 ymm ymm +// VPSRLQ xmm ymm ymm +// VPSRLQ m128 ymm ymm +func VPSRLQ(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLQ: bad operands") +} + +// VPSRLVD: Variable Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLVD xmm xmm xmm +// VPSRLVD m128 xmm xmm +// VPSRLVD ymm ymm ymm +// VPSRLVD m256 ymm ymm +func VPSRLVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLVD: bad operands") +} + +// VPSRLVQ: Variable Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLVQ xmm xmm xmm +// VPSRLVQ m128 xmm xmm +// VPSRLVQ ymm ymm ymm +// VPSRLVQ m256 ymm ymm +func VPSRLVQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLVQ: bad operands") +} + +// VPSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// VPSRLW imm8 xmm xmm +// VPSRLW xmm xmm xmm +// VPSRLW m128 xmm xmm +// VPSRLW imm8 ymm ymm +// VPSRLW xmm ymm ymm +// VPSRLW m128 ymm ymm +func VPSRLW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSRLW: bad operands") +} + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +func VPSUBB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBB: bad operands") +} + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +func VPSUBD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBD: bad operands") +} + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +func VPSUBQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBQ: bad operands") +} + +// VPSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSB xmm xmm xmm +// VPSUBSB m128 xmm xmm +// VPSUBSB ymm ymm ymm +// VPSUBSB m256 ymm ymm +func VPSUBSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBSB: bad operands") +} + +// VPSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSW xmm xmm xmm +// VPSUBSW m128 xmm xmm +// VPSUBSW ymm ymm ymm +// VPSUBSW m256 ymm ymm +func VPSUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBSW: bad operands") +} + +// VPSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSB xmm xmm xmm +// VPSUBUSB m128 xmm xmm +// VPSUBUSB ymm ymm ymm +// VPSUBUSB m256 ymm ymm +func VPSUBUSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBUSB: bad operands") +} + +// VPSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSW xmm xmm xmm +// VPSUBUSW m128 xmm xmm +// VPSUBUSW ymm ymm ymm +// VPSUBUSW m256 ymm ymm +func VPSUBUSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBUSW: bad operands") +} + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +func VPSUBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPSUBW: bad operands") +} + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +func VPTEST(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VPTEST: bad operands") +} + +// VPUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKHBW xmm xmm xmm +// VPUNPCKHBW m128 xmm xmm +// VPUNPCKHBW ymm ymm ymm +// VPUNPCKHBW m256 ymm ymm +func VPUNPCKHBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKHBW: bad operands") +} + +// VPUNPCKHDQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKHDQ xmm xmm xmm +// VPUNPCKHDQ m128 xmm xmm +// VPUNPCKHDQ ymm ymm ymm +// VPUNPCKHDQ m256 ymm ymm +func VPUNPCKHDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKHDQ: bad operands") +} + +// VPUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKHQDQ xmm xmm xmm +// VPUNPCKHQDQ m128 xmm xmm +// VPUNPCKHQDQ ymm ymm ymm +// VPUNPCKHQDQ m256 ymm ymm +func VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKHQDQ: bad operands") +} + +// VPUNPCKHWD: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKHWD xmm xmm xmm +// VPUNPCKHWD m128 xmm xmm +// VPUNPCKHWD ymm ymm ymm +// VPUNPCKHWD m256 ymm ymm +func VPUNPCKHWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKHWD: bad operands") +} + +// VPUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKLBW xmm xmm xmm +// VPUNPCKLBW m128 xmm xmm +// VPUNPCKLBW ymm ymm ymm +// VPUNPCKLBW m256 ymm ymm +func VPUNPCKLBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKLBW: bad operands") +} + +// VPUNPCKLDQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKLDQ xmm xmm xmm +// VPUNPCKLDQ m128 xmm xmm +// VPUNPCKLDQ ymm ymm ymm +// VPUNPCKLDQ m256 ymm ymm +func VPUNPCKLDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKLDQ: bad operands") +} + +// VPUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKLQDQ xmm xmm xmm +// VPUNPCKLQDQ m128 xmm xmm +// VPUNPCKLQDQ ymm ymm ymm +// VPUNPCKLQDQ m256 ymm ymm +func VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKLQDQ: bad operands") +} + +// VPUNPCKLWD: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKLWD xmm xmm xmm +// VPUNPCKLWD m128 xmm xmm +// VPUNPCKLWD ymm ymm ymm +// VPUNPCKLWD m256 ymm ymm +func VPUNPCKLWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPUNPCKLWD: bad operands") +} + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +func VPXOR(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX2"}, + }, nil + } + return nil, errors.New("VPXOR: bad operands") +} + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +func VRCPPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VRCPPS: bad operands") +} + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +func VRCPSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRCPSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRCPSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VRCPSS: bad operands") +} + +// VROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPD imm8 xmm xmm +// VROUNDPD imm8 m128 xmm +// VROUNDPD imm8 ymm ymm +// VROUNDPD imm8 m256 ymm +func VROUNDPD(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VROUNDPD: bad operands") +} + +// VROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPS imm8 xmm xmm +// VROUNDPS imm8 m128 xmm +// VROUNDPS imm8 ymm ymm +// VROUNDPS imm8 m256 ymm +func VROUNDPS(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VROUNDPS: bad operands") +} + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +func VROUNDSD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VROUNDSD: bad operands") +} + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +func VROUNDSS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VROUNDSS: bad operands") +} + +// VRSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRSQRTPS xmm xmm +// VRSQRTPS m128 xmm +// VRSQRTPS ymm ymm +// VRSQRTPS m256 ymm +func VRSQRTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VRSQRTPS: bad operands") +} + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +func VRSQRTSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VRSQRTSS: bad operands") +} + +// VSHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPD imm8 xmm xmm xmm +// VSHUFPD imm8 m128 xmm xmm +// VSHUFPD imm8 ymm ymm ymm +// VSHUFPD imm8 m256 ymm ymm +func VSHUFPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSHUFPD: bad operands") +} + +// VSHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPS imm8 xmm xmm xmm +// VSHUFPS imm8 m128 xmm xmm +// VSHUFPS imm8 ymm ymm ymm +// VSHUFPS imm8 m256 ymm ymm +func VSHUFPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSHUFPS: bad operands") +} + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +func VSQRTPD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSQRTPD: bad operands") +} + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +func VSQRTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSQRTPS: bad operands") +} + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +func VSQRTSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSQRTSD: bad operands") +} + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +func VSQRTSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSQRTSS: bad operands") +} + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +func VSTMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "VSTMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{m}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSTMXCSR: bad operands") +} + +// VSUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPD xmm xmm xmm +// VSUBPD m128 xmm xmm +// VSUBPD ymm ymm ymm +// VSUBPD m256 ymm ymm +func VSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSUBPD: bad operands") +} + +// VSUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPS xmm xmm xmm +// VSUBPS m128 xmm xmm +// VSUBPS ymm ymm ymm +// VSUBPS m256 ymm ymm +func VSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSUBPS: bad operands") +} + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +func VSUBSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSUBSD: bad operands") +} + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +func VSUBSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VSUBSS: bad operands") +} + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +func VTESTPD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VTESTPD: bad operands") +} + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +func VTESTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VTESTPS: bad operands") +} + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +func VUCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUCOMISD: bad operands") +} + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +func VUCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUCOMISS: bad operands") +} + +// VUNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPD xmm xmm xmm +// VUNPCKHPD m128 xmm xmm +// VUNPCKHPD ymm ymm ymm +// VUNPCKHPD m256 ymm ymm +func VUNPCKHPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUNPCKHPD: bad operands") +} + +// VUNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPS xmm xmm xmm +// VUNPCKHPS m128 xmm xmm +// VUNPCKHPS ymm ymm ymm +// VUNPCKHPS m256 ymm ymm +func VUNPCKHPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUNPCKHPS: bad operands") +} + +// VUNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPD xmm xmm xmm +// VUNPCKLPD m128 xmm xmm +// VUNPCKLPD ymm ymm ymm +// VUNPCKLPD m256 ymm ymm +func VUNPCKLPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUNPCKLPD: bad operands") +} + +// VUNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPS xmm xmm xmm +// VUNPCKLPS m128 xmm xmm +// VUNPCKLPS ymm ymm ymm +// VUNPCKLPS m256 ymm ymm +func VUNPCKLPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VUNPCKLPS: bad operands") +} + +// VXORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// VXORPD xmm xmm xmm +// VXORPD m128 xmm xmm +// VXORPD ymm ymm ymm +// VXORPD m256 ymm ymm +func VXORPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VXORPD: bad operands") +} + +// VXORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// VXORPS xmm xmm xmm +// VXORPS m128 xmm xmm +// VXORPS ymm ymm ymm +// VXORPS m256 ymm ymm +func VXORPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + CancellingInputs: true, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + ISA: []string{"AVX"}, + }, nil + } + return nil, errors.New("VXORPS: bad operands") +} + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +func VZEROALL() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "VZEROALL", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil +} + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +func VZEROUPPER() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "VZEROUPPER", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + ISA: []string{"AVX"}, + }, nil +} + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +func XADDB(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(r) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "XADDB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR8(r) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "XADDB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDB: bad operands") +} + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +func XADDL(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "XADDL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "XADDL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDL: bad operands") +} + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +func XADDQ(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XADDQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XADDQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDQ: bad operands") +} + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +func XADDW(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "XADDW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR16(r) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "XADDW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDW: bad operands") +} + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +func XCHGB(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsM8(mr) && operand.IsR8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR8(mr) && operand.IsM8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + } + return nil, errors.New("XCHGB: bad operands") +} + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +func XCHGL(emr, emr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(emr) && operand.IsEAX(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsEAX(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsR32(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsM32(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsR32(emr) && operand.IsM32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + } + return nil, errors.New("XCHGL: bad operands") +} + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +func XCHGQ(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsRAX(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsRAX(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR64(mr) && operand.IsM64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + } + return nil, errors.New("XCHGQ: bad operands") +} + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +func XCHGW(amr, amr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(amr) && operand.IsAX(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsAX(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsR16(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsM16(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsR16(amr) && operand.IsM16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + } + return nil, errors.New("XCHGW: bad operands") +} + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +func XGETBV() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "XGETBV", + Operands: nil, + Inputs: []operand.Op{reg.ECX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil +} + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +func XLAT() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "XLAT", + Operands: nil, + Inputs: []operand.Op{reg.AL, reg.EBX}, + Outputs: []operand.Op{reg.AL}, + }, nil +} + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +func XORB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("XORB: bad operands") +} + +// XORL: Logical Exclusive OR. +// +// Forms: +// +// XORL imm32 eax +// XORL imm8 r32 +// XORL imm32 r32 +// XORL r32 r32 +// XORL m32 r32 +// XORL imm8 m32 +// XORL imm32 m32 +// XORL r32 m32 +func XORL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + CancellingInputs: true, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("XORL: bad operands") +} + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +func XORPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE2"}, + }, nil + } + return nil, errors.New("XORPD: bad operands") +} + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +func XORPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + CancellingInputs: true, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + ISA: []string{"SSE"}, + }, nil + } + return nil, errors.New("XORPS: bad operands") +} + +// XORQ: Logical Exclusive OR. +// +// Forms: +// +// XORQ imm32 rax +// XORQ imm8 r64 +// XORQ imm32 r64 +// XORQ r64 r64 +// XORQ m64 r64 +// XORQ imm8 m64 +// XORQ imm32 m64 +// XORQ r64 m64 +func XORQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + CancellingInputs: true, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("XORQ: bad operands") +} + +// XORW: Logical Exclusive OR. +// +// Forms: +// +// XORW imm16 ax +// XORW imm8 r16 +// XORW imm16 r16 +// XORW r16 r16 +// XORW m16 r16 +// XORW imm8 m16 +// XORW imm16 m16 +// XORW r16 m16 +func XORW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + CancellingInputs: true, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("XORW: bad operands") +} |