From b2be91cdb52bafa809796d702166b3d60374b684 Mon Sep 17 00:00:00 2001 From: xtaci Date: Sun, 4 Oct 2020 22:40:04 +0800 Subject: [PATCH] add missing vendor files --- .../github.com/klauspost/cpuid/cpuid_arm64.s | 26 + .../klauspost/cpuid/detect_arm64.go | 219 + vendor/github.com/klauspost/cpuid/go.mod | 3 + .../klauspost/reedsolomon/galois_gen_amd64.go | 408 + .../klauspost/reedsolomon/galois_gen_amd64.s | 18526 +++++++++ .../klauspost/reedsolomon/galois_gen_none.go | 11 + .../reedsolomon/galois_gen_switch_amd64.go | 293 + .../klauspost/reedsolomon/galois_notamd64.go | 13 + .../github.com/klauspost/reedsolomon/gen.go | 249 + .../github.com/klauspost/reedsolomon/go.mod | 7 + .../github.com/klauspost/reedsolomon/go.sum | 2 + vendor/github.com/mmcloughlin/avo/LICENSE | 29 + .../github.com/mmcloughlin/avo/attr/attr.go | 102 + .../github.com/mmcloughlin/avo/build/attr.go | 18 + .../github.com/mmcloughlin/avo/build/cli.go | 171 + .../mmcloughlin/avo/build/context.go | 223 + .../github.com/mmcloughlin/avo/build/doc.go | 2 + .../github.com/mmcloughlin/avo/build/error.go | 88 + .../mmcloughlin/avo/build/global.go | 155 + .../mmcloughlin/avo/build/pseudo.go | 70 + .../mmcloughlin/avo/build/zinstructions.go | 26315 ++++++++++++ .../github.com/mmcloughlin/avo/build/zmov.go | 72 + .../mmcloughlin/avo/buildtags/buildtags.go | 312 + .../mmcloughlin/avo/gotypes/components.go | 253 + .../github.com/mmcloughlin/avo/gotypes/doc.go | 2 + .../mmcloughlin/avo/gotypes/signature.go | 177 + .../mmcloughlin/avo/internal/prnt/printer.go | 60 + .../mmcloughlin/avo/internal/stack/stack.go | 73 + vendor/github.com/mmcloughlin/avo/ir/doc.go | 2 + vendor/github.com/mmcloughlin/avo/ir/ir.go | 355 + .../mmcloughlin/avo/operand/checks.go | 247 + .../mmcloughlin/avo/operand/const.go | 36 + .../github.com/mmcloughlin/avo/operand/doc.go | 2 + .../mmcloughlin/avo/operand/types.go | 151 + .../mmcloughlin/avo/operand/zconst.go | 75 + .../github.com/mmcloughlin/avo/pass/alloc.go | 190 + vendor/github.com/mmcloughlin/avo/pass/cfg.go | 81 + .../mmcloughlin/avo/pass/cleanup.go | 123 + vendor/github.com/mmcloughlin/avo/pass/isa.go | 31 + .../github.com/mmcloughlin/avo/pass/pass.go | 100 + vendor/github.com/mmcloughlin/avo/pass/reg.go | 139 + .../mmcloughlin/avo/pass/textflag.go | 42 + .../github.com/mmcloughlin/avo/pass/verify.go | 32 + .../mmcloughlin/avo/printer/goasm.go | 186 + .../mmcloughlin/avo/printer/printer.go | 98 + .../mmcloughlin/avo/printer/stubs.go | 45 + .../mmcloughlin/avo/reg/collection.go | 54 + vendor/github.com/mmcloughlin/avo/reg/doc.go | 2 + vendor/github.com/mmcloughlin/avo/reg/set.go | 112 + .../github.com/mmcloughlin/avo/reg/types.go | 304 + vendor/github.com/mmcloughlin/avo/reg/x86.go | 331 + vendor/github.com/mmcloughlin/avo/src/src.go | 62 + vendor/github.com/mmcloughlin/avo/x86/doc.go | 2 + vendor/github.com/mmcloughlin/avo/x86/gen.go | 4 + .../github.com/mmcloughlin/avo/x86/zctors.go | 34629 ++++++++++++++++ vendor/golang.org/x/mod/LICENSE | 27 + vendor/golang.org/x/mod/PATENTS | 22 + vendor/golang.org/x/mod/semver/semver.go | 388 + .../sys/internal/unsafeheader/unsafeheader.go | 30 + vendor/golang.org/x/tools/AUTHORS | 3 + vendor/golang.org/x/tools/CONTRIBUTORS | 3 + vendor/golang.org/x/tools/LICENSE | 27 + vendor/golang.org/x/tools/PATENTS | 22 + .../x/tools/go/gcexportdata/gcexportdata.go | 109 + .../x/tools/go/gcexportdata/importer.go | 73 + .../x/tools/go/internal/gcimporter/bexport.go | 852 + .../x/tools/go/internal/gcimporter/bimport.go | 1039 + .../go/internal/gcimporter/exportdata.go | 93 + .../go/internal/gcimporter/gcimporter.go | 1078 + .../x/tools/go/internal/gcimporter/iexport.go | 739 + .../x/tools/go/internal/gcimporter/iimport.go | 630 + .../go/internal/gcimporter/newInterface10.go | 21 + .../go/internal/gcimporter/newInterface11.go | 13 + .../tools/go/internal/packagesdriver/sizes.go | 117 + vendor/golang.org/x/tools/go/packages/doc.go | 221 + .../x/tools/go/packages/external.go | 101 + .../golang.org/x/tools/go/packages/golist.go | 996 + .../x/tools/go/packages/golist_overlay.go | 473 + .../x/tools/go/packages/loadmode_string.go | 57 + .../x/tools/go/packages/packages.go | 1212 + .../golang.org/x/tools/go/packages/visit.go | 55 + .../x/tools/internal/event/core/event.go | 85 + .../x/tools/internal/event/core/export.go | 70 + .../x/tools/internal/event/core/fast.go | 77 + .../golang.org/x/tools/internal/event/doc.go | 7 + .../x/tools/internal/event/event.go | 127 + .../x/tools/internal/event/keys/keys.go | 564 + .../x/tools/internal/event/keys/standard.go | 22 + .../x/tools/internal/event/label/label.go | 213 + .../x/tools/internal/gocommand/invoke.go | 230 + .../x/tools/internal/gocommand/vendor.go | 102 + .../internal/packagesinternal/packages.go | 14 + .../x/tools/internal/typesinternal/types.go | 28 + vendor/golang.org/x/xerrors/LICENSE | 27 + vendor/golang.org/x/xerrors/PATENTS | 22 + vendor/golang.org/x/xerrors/README | 2 + vendor/golang.org/x/xerrors/adaptor.go | 193 + vendor/golang.org/x/xerrors/codereview.cfg | 1 + vendor/golang.org/x/xerrors/doc.go | 22 + vendor/golang.org/x/xerrors/errors.go | 33 + vendor/golang.org/x/xerrors/fmt.go | 187 + vendor/golang.org/x/xerrors/format.go | 34 + vendor/golang.org/x/xerrors/frame.go | 56 + vendor/golang.org/x/xerrors/go.mod | 3 + .../golang.org/x/xerrors/internal/internal.go | 8 + vendor/golang.org/x/xerrors/wrap.go | 106 + 106 files changed, 95948 insertions(+) create mode 100644 vendor/github.com/klauspost/cpuid/cpuid_arm64.s create mode 100644 vendor/github.com/klauspost/cpuid/detect_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/go.mod create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.go create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_none.go create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_notamd64.go create mode 100644 vendor/github.com/klauspost/reedsolomon/gen.go create mode 100644 vendor/github.com/klauspost/reedsolomon/go.mod create mode 100644 vendor/github.com/klauspost/reedsolomon/go.sum create mode 100644 vendor/github.com/mmcloughlin/avo/LICENSE create mode 100644 vendor/github.com/mmcloughlin/avo/attr/attr.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/attr.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/cli.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/context.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/error.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/global.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/pseudo.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/zinstructions.go create mode 100644 vendor/github.com/mmcloughlin/avo/build/zmov.go create mode 100644 vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go create mode 100644 vendor/github.com/mmcloughlin/avo/gotypes/components.go create mode 100644 vendor/github.com/mmcloughlin/avo/gotypes/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/gotypes/signature.go create mode 100644 vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go create mode 100644 vendor/github.com/mmcloughlin/avo/internal/stack/stack.go create mode 100644 vendor/github.com/mmcloughlin/avo/ir/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/ir/ir.go create mode 100644 vendor/github.com/mmcloughlin/avo/operand/checks.go create mode 100644 vendor/github.com/mmcloughlin/avo/operand/const.go create mode 100644 vendor/github.com/mmcloughlin/avo/operand/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/operand/types.go create mode 100644 vendor/github.com/mmcloughlin/avo/operand/zconst.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/alloc.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/cfg.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/cleanup.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/isa.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/pass.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/reg.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/textflag.go create mode 100644 vendor/github.com/mmcloughlin/avo/pass/verify.go create mode 100644 vendor/github.com/mmcloughlin/avo/printer/goasm.go create mode 100644 vendor/github.com/mmcloughlin/avo/printer/printer.go create mode 100644 vendor/github.com/mmcloughlin/avo/printer/stubs.go create mode 100644 vendor/github.com/mmcloughlin/avo/reg/collection.go create mode 100644 vendor/github.com/mmcloughlin/avo/reg/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/reg/set.go create mode 100644 vendor/github.com/mmcloughlin/avo/reg/types.go create mode 100644 vendor/github.com/mmcloughlin/avo/reg/x86.go create mode 100644 vendor/github.com/mmcloughlin/avo/src/src.go create mode 100644 vendor/github.com/mmcloughlin/avo/x86/doc.go create mode 100644 vendor/github.com/mmcloughlin/avo/x86/gen.go create mode 100644 vendor/github.com/mmcloughlin/avo/x86/zctors.go create mode 100644 vendor/golang.org/x/mod/LICENSE create mode 100644 vendor/golang.org/x/mod/PATENTS create mode 100644 vendor/golang.org/x/mod/semver/semver.go create mode 100644 vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go create mode 100644 vendor/golang.org/x/tools/AUTHORS create mode 100644 vendor/golang.org/x/tools/CONTRIBUTORS create mode 100644 vendor/golang.org/x/tools/LICENSE create mode 100644 vendor/golang.org/x/tools/PATENTS create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go create mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go create mode 100644 vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go create mode 100644 vendor/golang.org/x/tools/go/packages/doc.go create mode 100644 vendor/golang.org/x/tools/go/packages/external.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist.go create mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go create mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go create mode 100644 vendor/golang.org/x/tools/go/packages/packages.go create mode 100644 vendor/golang.org/x/tools/go/packages/visit.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/export.go create mode 100644 vendor/golang.org/x/tools/internal/event/core/fast.go create mode 100644 vendor/golang.org/x/tools/internal/event/doc.go create mode 100644 vendor/golang.org/x/tools/internal/event/event.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/keys.go create mode 100644 vendor/golang.org/x/tools/internal/event/keys/standard.go create mode 100644 vendor/golang.org/x/tools/internal/event/label/label.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/invoke.go create mode 100644 vendor/golang.org/x/tools/internal/gocommand/vendor.go create mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go create mode 100644 vendor/golang.org/x/xerrors/LICENSE create mode 100644 vendor/golang.org/x/xerrors/PATENTS create mode 100644 vendor/golang.org/x/xerrors/README create mode 100644 vendor/golang.org/x/xerrors/adaptor.go create mode 100644 vendor/golang.org/x/xerrors/codereview.cfg create mode 100644 vendor/golang.org/x/xerrors/doc.go create mode 100644 vendor/golang.org/x/xerrors/errors.go create mode 100644 vendor/golang.org/x/xerrors/fmt.go create mode 100644 vendor/golang.org/x/xerrors/format.go create mode 100644 vendor/golang.org/x/xerrors/frame.go create mode 100644 vendor/golang.org/x/xerrors/go.mod create mode 100644 vendor/golang.org/x/xerrors/internal/internal.go create mode 100644 vendor/golang.org/x/xerrors/wrap.go diff --git a/vendor/github.com/klauspost/cpuid/cpuid_arm64.s b/vendor/github.com/klauspost/cpuid/cpuid_arm64.s new file mode 100644 index 0000000..8975ee8 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/cpuid_arm64.s @@ -0,0 +1,26 @@ +// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. + +//+build arm64,!gccgo + +// See https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt + +// func getMidr +TEXT ·getMidr(SB), 7, $0 + WORD $0xd5380000 // mrs x0, midr_el1 /* Main ID Register */ + MOVD R0, midr+0(FP) + RET + +// func getProcFeatures +TEXT ·getProcFeatures(SB), 7, $0 + WORD $0xd5380400 // mrs x0, id_aa64pfr0_el1 /* Processor Feature Register 0 */ + MOVD R0, procFeatures+0(FP) + RET + +// func getInstAttributes +TEXT ·getInstAttributes(SB), 7, $0 + WORD $0xd5380600 // mrs x0, id_aa64isar0_el1 /* Instruction Set Attribute Register 0 */ + WORD $0xd5380621 // mrs x1, id_aa64isar1_el1 /* Instruction Set Attribute Register 1 */ + MOVD R0, instAttrReg0+0(FP) + MOVD R1, instAttrReg1+8(FP) + RET + diff --git a/vendor/github.com/klauspost/cpuid/detect_arm64.go b/vendor/github.com/klauspost/cpuid/detect_arm64.go new file mode 100644 index 0000000..923a826 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/detect_arm64.go @@ -0,0 +1,219 @@ +// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. + +//+build arm64,!gccgo,!noasm,!appengine + +package cpuid + +func getMidr() (midr uint64) +func getProcFeatures() (procFeatures uint64) +func getInstAttributes() (instAttrReg0, instAttrReg1 uint64) + +func initCPU() { + cpuid = func(uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + cpuidex = func(x, y uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + xgetbv = func(uint32) (a, b uint32) { return 0, 0 } + rdtscpAsm = func() (a, b, c, d uint32) { return 0, 0, 0, 0 } +} + +func addInfo(c *CPUInfo) { + // ARM64 disabled for now. + if true { + return + } + // midr := getMidr() + + // MIDR_EL1 - Main ID Register + // x--------------------------------------------------x + // | Name | bits | visible | + // |--------------------------------------------------| + // | Implementer | [31-24] | y | + // |--------------------------------------------------| + // | Variant | [23-20] | y | + // |--------------------------------------------------| + // | Architecture | [19-16] | y | + // |--------------------------------------------------| + // | PartNum | [15-4] | y | + // |--------------------------------------------------| + // | Revision | [3-0] | y | + // x--------------------------------------------------x + + // fmt.Printf(" implementer: 0x%02x\n", (midr>>24)&0xff) + // fmt.Printf(" variant: 0x%01x\n", (midr>>20)&0xf) + // fmt.Printf("architecture: 0x%01x\n", (midr>>16)&0xf) + // fmt.Printf(" part num: 0x%03x\n", (midr>>4)&0xfff) + // fmt.Printf(" revision: 0x%01x\n", (midr>>0)&0xf) + + procFeatures := getProcFeatures() + + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + // x--------------------------------------------------x + // | Name | bits | visible | + // |--------------------------------------------------| + // | DIT | [51-48] | y | + // |--------------------------------------------------| + // | SVE | [35-32] | y | + // |--------------------------------------------------| + // | GIC | [27-24] | n | + // |--------------------------------------------------| + // | AdvSIMD | [23-20] | y | + // |--------------------------------------------------| + // | FP | [19-16] | y | + // |--------------------------------------------------| + // | EL3 | [15-12] | n | + // |--------------------------------------------------| + // | EL2 | [11-8] | n | + // |--------------------------------------------------| + // | EL1 | [7-4] | n | + // |--------------------------------------------------| + // | EL0 | [3-0] | n | + // x--------------------------------------------------x + + var f ArmFlags + // if procFeatures&(0xf<<48) != 0 { + // fmt.Println("DIT") + // } + if procFeatures&(0xf<<32) != 0 { + f |= SVE + } + if procFeatures&(0xf<<20) != 15<<20 { + f |= ASIMD + if procFeatures&(0xf<<20) == 1<<20 { + // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64pfr0_el1 + // 0b0001 --> As for 0b0000, and also includes support for half-precision floating-point arithmetic. + f |= FPHP + f |= ASIMDHP + } + } + if procFeatures&(0xf<<16) != 0 { + f |= FP + } + + instAttrReg0, instAttrReg1 := getInstAttributes() + + // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1 + // + // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 + // x--------------------------------------------------x + // | Name | bits | visible | + // |--------------------------------------------------| + // | TS | [55-52] | y | + // |--------------------------------------------------| + // | FHM | [51-48] | y | + // |--------------------------------------------------| + // | DP | [47-44] | y | + // |--------------------------------------------------| + // | SM4 | [43-40] | y | + // |--------------------------------------------------| + // | SM3 | [39-36] | y | + // |--------------------------------------------------| + // | SHA3 | [35-32] | y | + // |--------------------------------------------------| + // | RDM | [31-28] | y | + // |--------------------------------------------------| + // | ATOMICS | [23-20] | y | + // |--------------------------------------------------| + // | CRC32 | [19-16] | y | + // |--------------------------------------------------| + // | SHA2 | [15-12] | y | + // |--------------------------------------------------| + // | SHA1 | [11-8] | y | + // |--------------------------------------------------| + // | AES | [7-4] | y | + // x--------------------------------------------------x + + // if instAttrReg0&(0xf<<52) != 0 { + // fmt.Println("TS") + // } + // if instAttrReg0&(0xf<<48) != 0 { + // fmt.Println("FHM") + // } + if instAttrReg0&(0xf<<44) != 0 { + f |= ASIMDDP + } + if instAttrReg0&(0xf<<40) != 0 { + f |= SM4 + } + if instAttrReg0&(0xf<<36) != 0 { + f |= SM3 + } + if instAttrReg0&(0xf<<32) != 0 { + f |= SHA3 + } + if instAttrReg0&(0xf<<28) != 0 { + f |= ASIMDRDM + } + if instAttrReg0&(0xf<<20) != 0 { + f |= ATOMICS + } + if instAttrReg0&(0xf<<16) != 0 { + f |= CRC32 + } + if instAttrReg0&(0xf<<12) != 0 { + f |= SHA2 + } + if instAttrReg0&(0xf<<12) == 2<<12 { + // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1 + // 0b0010 --> As 0b0001, plus SHA512H, SHA512H2, SHA512SU0, and SHA512SU1 instructions implemented. + f |= SHA512 + } + if instAttrReg0&(0xf<<8) != 0 { + f |= SHA1 + } + if instAttrReg0&(0xf<<4) != 0 { + f |= AES + } + if instAttrReg0&(0xf<<4) == 2<<4 { + // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1 + // 0b0010 --> As for 0b0001, plus PMULL/PMULL2 instructions operating on 64-bit data quantities. + f |= PMULL + } + + // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar1_el1 + // + // ID_AA64ISAR1_EL1 - Instruction set attribute register 1 + // x--------------------------------------------------x + // | Name | bits | visible | + // |--------------------------------------------------| + // | GPI | [31-28] | y | + // |--------------------------------------------------| + // | GPA | [27-24] | y | + // |--------------------------------------------------| + // | LRCPC | [23-20] | y | + // |--------------------------------------------------| + // | FCMA | [19-16] | y | + // |--------------------------------------------------| + // | JSCVT | [15-12] | y | + // |--------------------------------------------------| + // | API | [11-8] | y | + // |--------------------------------------------------| + // | APA | [7-4] | y | + // |--------------------------------------------------| + // | DPB | [3-0] | y | + // x--------------------------------------------------x + + // if instAttrReg1&(0xf<<28) != 0 { + // fmt.Println("GPI") + // } + if instAttrReg1&(0xf<<28) != 24 { + f |= GPA + } + if instAttrReg1&(0xf<<20) != 0 { + f |= LRCPC + } + if instAttrReg1&(0xf<<16) != 0 { + f |= FCMA + } + if instAttrReg1&(0xf<<12) != 0 { + f |= JSCVT + } + // if instAttrReg1&(0xf<<8) != 0 { + // fmt.Println("API") + // } + // if instAttrReg1&(0xf<<4) != 0 { + // fmt.Println("APA") + // } + if instAttrReg1&(0xf<<0) != 0 { + f |= DCPOP + } + c.Arm = f +} diff --git a/vendor/github.com/klauspost/cpuid/go.mod b/vendor/github.com/klauspost/cpuid/go.mod new file mode 100644 index 0000000..55563f2 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/go.mod @@ -0,0 +1,3 @@ +module github.com/klauspost/cpuid + +go 1.12 diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.go new file mode 100644 index 0000000..edd6376 --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.go @@ -0,0 +1,408 @@ +// Code generated by command: go run gen.go -out galois_gen_amd64.s -stubs galois_gen_amd64.go. DO NOT EDIT. + +// +build !appengine +// +build !noasm +// +build !nogen +// +build gc + +package reedsolomon + +// mulAvxTwo_1x1 takes 1 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x2 takes 1 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x3 takes 1 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x4 takes 1 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x5 takes 1 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x6 takes 1 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x7 takes 1 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_1x8 takes 1 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_1x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x1 takes 2 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x2 takes 2 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x3 takes 2 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x4 takes 2 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x5 takes 2 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x6 takes 2 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x7 takes 2 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_2x8 takes 2 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_2x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x1 takes 3 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x2 takes 3 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x3 takes 3 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x4 takes 3 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x5 takes 3 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x6 takes 3 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x7 takes 3 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_3x8 takes 3 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_3x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x1 takes 4 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x2 takes 4 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x3 takes 4 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x4 takes 4 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x5 takes 4 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x6 takes 4 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x7 takes 4 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_4x8 takes 4 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_4x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x1 takes 5 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x2 takes 5 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x3 takes 5 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x4 takes 5 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x5 takes 5 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x6 takes 5 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x7 takes 5 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_5x8 takes 5 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_5x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x1 takes 6 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x2 takes 6 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x3 takes 6 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x4 takes 6 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x5 takes 6 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x6 takes 6 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x7 takes 6 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_6x8 takes 6 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_6x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x1 takes 7 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x2 takes 7 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x3 takes 7 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x4 takes 7 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x5 takes 7 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x6 takes 7 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x7 takes 7 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_7x8 takes 7 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_7x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x1 takes 8 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x2 takes 8 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x3 takes 8 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x4 takes 8 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x5 takes 8 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x6 takes 8 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x7 takes 8 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_8x8 takes 8 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_8x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x1 takes 9 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x2 takes 9 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x3 takes 9 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x4 takes 9 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x5 takes 9 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x6 takes 9 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x7 takes 9 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_9x8 takes 9 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_9x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x1 takes 10 inputs and produces 1 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x2 takes 10 inputs and produces 2 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x3 takes 10 inputs and produces 3 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x4 takes 10 inputs and produces 4 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x5 takes 10 inputs and produces 5 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x6 takes 10 inputs and produces 6 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x7 takes 10 inputs and produces 7 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) + +// mulAvxTwo_10x8 takes 10 inputs and produces 8 outputs. +// The output is initialized to 0. +//go:noescape +func mulAvxTwo_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s new file mode 100644 index 0000000..c76db3c --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s @@ -0,0 +1,18526 @@ +// Code generated by command: go run gen.go -out galois_gen_amd64.s -stubs galois_gen_amd64.go. DO NOT EDIT. + +// +build !appengine +// +build !noasm +// +build !nogen +// +build gc + +// func mulAvxTwo_1x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 6 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + MOVQ in_base+24(FP), CX + MOVQ (CX), CX + MOVQ $0x0000000f, BX + MOVQ BX, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), BX + +mulAvxTwo_1x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (CX)(BX*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y3, Y4, Y4 + VPAND Y3, Y5, Y5 + VPSHUFB Y4, Y1, Y4 + VPSHUFB Y5, Y2, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(BX*1) + + // Prepare for next loop + ADDQ $0x20, BX + DECQ AX + JNZ mulAvxTwo_1x1_loop + VZEROUPPER + +mulAvxTwo_1x1_end: + RET + +// func mulAvxTwo_1x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x2(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 11 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + MOVQ in_base+24(FP), CX + MOVQ (CX), CX + MOVQ $0x0000000f, BP + MOVQ BP, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), BP + +mulAvxTwo_1x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (CX)(BP*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VPSHUFB Y9, Y2, Y7 + VPSHUFB Y10, Y3, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VPSHUFB Y9, Y4, Y7 + VPSHUFB Y10, Y5, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(BP*1) + VMOVDQU Y1, (DX)(BP*1) + + // Prepare for next loop + ADDQ $0x20, BP + DECQ AX + JNZ mulAvxTwo_1x2_loop + VZEROUPPER + +mulAvxTwo_1x2_end: + RET + +// func mulAvxTwo_1x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x3(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 14 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + MOVQ in_base+24(FP), CX + MOVQ (CX), CX + MOVQ $0x0000000f, SI + MOVQ SI, X9 + VPBROADCASTB X9, Y9 + MOVQ start+72(FP), SI + +mulAvxTwo_1x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (CX)(SI*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y9, Y12, Y12 + VPAND Y9, Y13, Y13 + VPSHUFB Y12, Y3, Y10 + VPSHUFB Y13, Y4, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y0, Y0 + VPSHUFB Y12, Y5, Y10 + VPSHUFB Y13, Y6, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y1, Y1 + VPSHUFB Y12, Y7, Y10 + VPSHUFB Y13, Y8, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(SI*1) + VMOVDQU Y1, (BP)(SI*1) + VMOVDQU Y2, (DX)(SI*1) + + // Prepare for next loop + ADDQ $0x20, SI + DECQ AX + JNZ mulAvxTwo_1x3_loop + VZEROUPPER + +mulAvxTwo_1x3_end: + RET + +// func mulAvxTwo_1x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 17 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), DI + MOVQ $0x0000000f, R8 + MOVQ R8, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R8 + +mulAvxTwo_1x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (DI)(R8*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R8*1) + VMOVDQU Y1, (BP)(R8*1) + VMOVDQU Y2, (SI)(R8*1) + VMOVDQU Y3, (DX)(R8*1) + + // Prepare for next loop + ADDQ $0x20, R8 + DECQ AX + JNZ mulAvxTwo_1x4_loop + VZEROUPPER + +mulAvxTwo_1x4_end: + RET + +// func mulAvxTwo_1x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 20 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R8 + MOVQ $0x0000000f, R9 + MOVQ R9, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R9 + +mulAvxTwo_1x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R8)(R9*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R9*1) + VMOVDQU Y1, (BP)(R9*1) + VMOVDQU Y2, (SI)(R9*1) + VMOVDQU Y3, (DI)(R9*1) + VMOVDQU Y4, (DX)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_1x5_loop + VZEROUPPER + +mulAvxTwo_1x5_end: + RET + +// func mulAvxTwo_1x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 23 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R9 + MOVQ $0x0000000f, R10 + MOVQ R10, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R10 + +mulAvxTwo_1x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R9)(R10*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R10*1) + VMOVDQU Y1, (BP)(R10*1) + VMOVDQU Y2, (SI)(R10*1) + VMOVDQU Y3, (DI)(R10*1) + VMOVDQU Y4, (R8)(R10*1) + VMOVDQU Y5, (DX)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_1x6_loop + VZEROUPPER + +mulAvxTwo_1x6_end: + RET + +// func mulAvxTwo_1x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 26 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x7_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), DX + MOVQ in_base+24(FP), R10 + MOVQ (R10), R10 + MOVQ $0x0000000f, R11 + MOVQ R11, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R11 + +mulAvxTwo_1x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (R10)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (BP)(R11*1) + VMOVDQU Y2, (SI)(R11*1) + VMOVDQU Y3, (DI)(R11*1) + VMOVDQU Y4, (R8)(R11*1) + VMOVDQU Y5, (R9)(R11*1) + VMOVDQU Y6, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_1x7_loop + VZEROUPPER + +mulAvxTwo_1x7_end: + RET + +// func mulAvxTwo_1x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_1x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 29 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_1x8_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), R10 + MOVQ 168(DX), DX + MOVQ in_base+24(FP), R11 + MOVQ (R11), R11 + MOVQ $0x0000000f, R12 + MOVQ R12, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R12 + +mulAvxTwo_1x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (R11)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (SI)(R12*1) + VMOVDQU Y3, (DI)(R12*1) + VMOVDQU Y4, (R8)(R12*1) + VMOVDQU Y5, (R9)(R12*1) + VMOVDQU Y6, (R10)(R12*1) + VMOVDQU Y7, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_1x8_loop + VZEROUPPER + +mulAvxTwo_1x8_end: + RET + +// func mulAvxTwo_2x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 8 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + MOVQ in_base+24(FP), CX + MOVQ (CX), BX + MOVQ 24(CX), CX + MOVQ $0x0000000f, BP + MOVQ BP, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), BP + +mulAvxTwo_2x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BX)(BP*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y5, Y6, Y6 + VPAND Y5, Y7, Y7 + VPSHUFB Y6, Y1, Y6 + VPSHUFB Y7, Y2, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (CX)(BP*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y5, Y6, Y6 + VPAND Y5, Y7, Y7 + VPSHUFB Y6, Y3, Y6 + VPSHUFB Y7, Y4, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(BP*1) + + // Prepare for next loop + ADDQ $0x20, BP + DECQ AX + JNZ mulAvxTwo_2x1_loop + VZEROUPPER + +mulAvxTwo_2x1_end: + RET + +// func mulAvxTwo_2x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x2(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 15 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + MOVQ in_base+24(FP), CX + MOVQ (CX), BP + MOVQ 24(CX), CX + MOVQ $0x0000000f, SI + MOVQ SI, X10 + VPBROADCASTB X10, Y10 + MOVQ start+72(FP), SI + +mulAvxTwo_2x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (BP)(SI*1), Y13 + VPSRLQ $0x04, Y13, Y14 + VPAND Y10, Y13, Y13 + VPAND Y10, Y14, Y14 + VPSHUFB Y13, Y2, Y11 + VPSHUFB Y14, Y3, Y12 + VPXOR Y11, Y12, Y11 + VPXOR Y11, Y0, Y0 + VPSHUFB Y13, Y4, Y11 + VPSHUFB Y14, Y5, Y12 + VPXOR Y11, Y12, Y11 + VPXOR Y11, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (CX)(SI*1), Y13 + VPSRLQ $0x04, Y13, Y14 + VPAND Y10, Y13, Y13 + VPAND Y10, Y14, Y14 + VPSHUFB Y13, Y6, Y11 + VPSHUFB Y14, Y7, Y12 + VPXOR Y11, Y12, Y11 + VPXOR Y11, Y0, Y0 + VPSHUFB Y13, Y8, Y11 + VPSHUFB Y14, Y9, Y12 + VPXOR Y11, Y12, Y11 + VPXOR Y11, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(SI*1) + VMOVDQU Y1, (DX)(SI*1) + + // Prepare for next loop + ADDQ $0x20, SI + DECQ AX + JNZ mulAvxTwo_2x2_loop + VZEROUPPER + +mulAvxTwo_2x2_end: + RET + +// func mulAvxTwo_2x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 20 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), SI + MOVQ $0x0000000f, R8 + MOVQ R8, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R8 + +mulAvxTwo_2x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R8*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (SI)(R8*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R8*1) + VMOVDQU Y1, (BP)(R8*1) + VMOVDQU Y2, (DX)(R8*1) + + // Prepare for next loop + ADDQ $0x20, R8 + DECQ AX + JNZ mulAvxTwo_2x3_loop + VZEROUPPER + +mulAvxTwo_2x3_end: + RET + +// func mulAvxTwo_2x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 25 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), DI + MOVQ $0x0000000f, R9 + MOVQ R9, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R9 + +mulAvxTwo_2x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R9*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (DI)(R9*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R9*1) + VMOVDQU Y1, (BP)(R9*1) + VMOVDQU Y2, (SI)(R9*1) + VMOVDQU Y3, (DX)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_2x4_loop + VZEROUPPER + +mulAvxTwo_2x4_end: + RET + +// func mulAvxTwo_2x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 30 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R8 + MOVQ $0x0000000f, R10 + MOVQ R10, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R10 + +mulAvxTwo_2x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R10*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R8)(R10*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R10*1) + VMOVDQU Y1, (BP)(R10*1) + VMOVDQU Y2, (SI)(R10*1) + VMOVDQU Y3, (DI)(R10*1) + VMOVDQU Y4, (DX)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_2x5_loop + VZEROUPPER + +mulAvxTwo_2x5_end: + RET + +// func mulAvxTwo_2x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 35 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R10 + MOVQ 24(R9), R9 + MOVQ $0x0000000f, R11 + MOVQ R11, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R11 + +mulAvxTwo_2x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R10)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (R9)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (BP)(R11*1) + VMOVDQU Y2, (SI)(R11*1) + VMOVDQU Y3, (DI)(R11*1) + VMOVDQU Y4, (R8)(R11*1) + VMOVDQU Y5, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_2x6_loop + VZEROUPPER + +mulAvxTwo_2x6_end: + RET + +// func mulAvxTwo_2x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 40 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x7_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), DX + MOVQ in_base+24(FP), R10 + MOVQ (R10), R11 + MOVQ 24(R10), R10 + MOVQ $0x0000000f, R12 + MOVQ R12, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R12 + +mulAvxTwo_2x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (R11)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (R10)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (SI)(R12*1) + VMOVDQU Y3, (DI)(R12*1) + VMOVDQU Y4, (R8)(R12*1) + VMOVDQU Y5, (R9)(R12*1) + VMOVDQU Y6, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_2x7_loop + VZEROUPPER + +mulAvxTwo_2x7_end: + RET + +// func mulAvxTwo_2x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_2x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 45 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_2x8_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), R10 + MOVQ 168(DX), DX + MOVQ in_base+24(FP), R11 + MOVQ (R11), R12 + MOVQ 24(R11), R11 + MOVQ $0x0000000f, R13 + MOVQ R13, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R13 + +mulAvxTwo_2x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (R12)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (R11)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (SI)(R13*1) + VMOVDQU Y3, (DI)(R13*1) + VMOVDQU Y4, (R8)(R13*1) + VMOVDQU Y5, (R9)(R13*1) + VMOVDQU Y6, (R10)(R13*1) + VMOVDQU Y7, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_2x8_loop + VZEROUPPER + +mulAvxTwo_2x8_end: + RET + +// func mulAvxTwo_3x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 10 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + MOVQ in_base+24(FP), CX + MOVQ (CX), BX + MOVQ 24(CX), BP + MOVQ 48(CX), CX + MOVQ $0x0000000f, SI + MOVQ SI, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), SI + +mulAvxTwo_3x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BX)(SI*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y7, Y8, Y8 + VPAND Y7, Y9, Y9 + VPSHUFB Y8, Y1, Y8 + VPSHUFB Y9, Y2, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (BP)(SI*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y7, Y8, Y8 + VPAND Y7, Y9, Y9 + VPSHUFB Y8, Y3, Y8 + VPSHUFB Y9, Y4, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (CX)(SI*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y7, Y8, Y8 + VPAND Y7, Y9, Y9 + VPSHUFB Y8, Y5, Y8 + VPSHUFB Y9, Y6, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(SI*1) + + // Prepare for next loop + ADDQ $0x20, SI + DECQ AX + JNZ mulAvxTwo_3x1_loop + VZEROUPPER + +mulAvxTwo_3x1_end: + RET + +// func mulAvxTwo_3x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 19 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), BP + MOVQ $0x0000000f, R8 + MOVQ R8, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R8 + +mulAvxTwo_3x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R8*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R8*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (BP)(R8*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R8*1) + VMOVDQU Y1, (DX)(R8*1) + + // Prepare for next loop + ADDQ $0x20, R8 + DECQ AX + JNZ mulAvxTwo_3x2_loop + VZEROUPPER + +mulAvxTwo_3x2_end: + RET + +// func mulAvxTwo_3x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 26 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), SI + MOVQ $0x0000000f, R9 + MOVQ R9, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R9 + +mulAvxTwo_3x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R9*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R9*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (SI)(R9*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R9*1) + VMOVDQU Y1, (BP)(R9*1) + VMOVDQU Y2, (DX)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_3x3_loop + VZEROUPPER + +mulAvxTwo_3x3_end: + RET + +// func mulAvxTwo_3x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 33 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), DI + MOVQ $0x0000000f, R10 + MOVQ R10, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R10 + +mulAvxTwo_3x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R10*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R10*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (DI)(R10*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R10*1) + VMOVDQU Y1, (BP)(R10*1) + VMOVDQU Y2, (SI)(R10*1) + VMOVDQU Y3, (DX)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_3x4_loop + VZEROUPPER + +mulAvxTwo_3x4_end: + RET + +// func mulAvxTwo_3x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 40 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R10 + MOVQ 48(R8), R8 + MOVQ $0x0000000f, R11 + MOVQ R11, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R11 + +mulAvxTwo_3x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R11*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R10)(R11*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (R8)(R11*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (BP)(R11*1) + VMOVDQU Y2, (SI)(R11*1) + VMOVDQU Y3, (DI)(R11*1) + VMOVDQU Y4, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_3x5_loop + VZEROUPPER + +mulAvxTwo_3x5_end: + RET + +// func mulAvxTwo_3x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 47 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R10 + MOVQ 24(R9), R11 + MOVQ 48(R9), R9 + MOVQ $0x0000000f, R12 + MOVQ R12, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R12 + +mulAvxTwo_3x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R10)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (R11)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (R9)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (SI)(R12*1) + VMOVDQU Y3, (DI)(R12*1) + VMOVDQU Y4, (R8)(R12*1) + VMOVDQU Y5, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_3x6_loop + VZEROUPPER + +mulAvxTwo_3x6_end: + RET + +// func mulAvxTwo_3x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 54 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x7_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), DX + MOVQ in_base+24(FP), R10 + MOVQ (R10), R11 + MOVQ 24(R10), R12 + MOVQ 48(R10), R10 + MOVQ $0x0000000f, R13 + MOVQ R13, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R13 + +mulAvxTwo_3x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (R11)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (R12)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (R10)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (SI)(R13*1) + VMOVDQU Y3, (DI)(R13*1) + VMOVDQU Y4, (R8)(R13*1) + VMOVDQU Y5, (R9)(R13*1) + VMOVDQU Y6, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_3x7_loop + VZEROUPPER + +mulAvxTwo_3x7_end: + RET + +// func mulAvxTwo_3x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_3x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 61 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_3x8_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), R10 + MOVQ 168(DX), DX + MOVQ in_base+24(FP), R11 + MOVQ (R11), R12 + MOVQ 24(R11), R13 + MOVQ 48(R11), R11 + MOVQ $0x0000000f, R14 + MOVQ R14, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R14 + +mulAvxTwo_3x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (R12)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (R13)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (R11)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (SI)(R14*1) + VMOVDQU Y3, (DI)(R14*1) + VMOVDQU Y4, (R8)(R14*1) + VMOVDQU Y5, (R9)(R14*1) + VMOVDQU Y6, (R10)(R14*1) + VMOVDQU Y7, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_3x8_loop + VZEROUPPER + +mulAvxTwo_3x8_end: + RET + +// func mulAvxTwo_4x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 12 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + MOVQ in_base+24(FP), CX + MOVQ (CX), BX + MOVQ 24(CX), BP + MOVQ 48(CX), SI + MOVQ 72(CX), CX + MOVQ $0x0000000f, DI + MOVQ DI, X9 + VPBROADCASTB X9, Y9 + MOVQ start+72(FP), DI + +mulAvxTwo_4x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BX)(DI*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y9, Y10, Y10 + VPAND Y9, Y11, Y11 + VPSHUFB Y10, Y1, Y10 + VPSHUFB Y11, Y2, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (BP)(DI*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y9, Y10, Y10 + VPAND Y9, Y11, Y11 + VPSHUFB Y10, Y3, Y10 + VPSHUFB Y11, Y4, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (SI)(DI*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y9, Y10, Y10 + VPAND Y9, Y11, Y11 + VPSHUFB Y10, Y5, Y10 + VPSHUFB Y11, Y6, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (CX)(DI*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y9, Y10, Y10 + VPAND Y9, Y11, Y11 + VPSHUFB Y10, Y7, Y10 + VPSHUFB Y11, Y8, Y11 + VPXOR Y10, Y11, Y10 + VPXOR Y10, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(DI*1) + + // Prepare for next loop + ADDQ $0x20, DI + DECQ AX + JNZ mulAvxTwo_4x1_loop + VZEROUPPER + +mulAvxTwo_4x1_end: + RET + +// func mulAvxTwo_4x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 23 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), BP + MOVQ $0x0000000f, R9 + MOVQ R9, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R9 + +mulAvxTwo_4x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R9*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R9*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R9*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (BP)(R9*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R9*1) + VMOVDQU Y1, (DX)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_4x2_loop + VZEROUPPER + +mulAvxTwo_4x2_end: + RET + +// func mulAvxTwo_4x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 32 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), SI + MOVQ $0x0000000f, R10 + MOVQ R10, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R10 + +mulAvxTwo_4x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R10*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R10*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R10*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (SI)(R10*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R10*1) + VMOVDQU Y1, (BP)(R10*1) + VMOVDQU Y2, (DX)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_4x3_loop + VZEROUPPER + +mulAvxTwo_4x3_end: + RET + +// func mulAvxTwo_4x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 41 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), R10 + MOVQ 72(DI), DI + MOVQ $0x0000000f, R11 + MOVQ R11, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R11 + +mulAvxTwo_4x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R11*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R11*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (R10)(R11*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (DI)(R11*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (BP)(R11*1) + VMOVDQU Y2, (SI)(R11*1) + VMOVDQU Y3, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_4x4_loop + VZEROUPPER + +mulAvxTwo_4x4_end: + RET + +// func mulAvxTwo_4x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 50 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R10 + MOVQ 48(R8), R11 + MOVQ 72(R8), R8 + MOVQ $0x0000000f, R12 + MOVQ R12, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R12 + +mulAvxTwo_4x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R10)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (R11)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R8)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (SI)(R12*1) + VMOVDQU Y3, (DI)(R12*1) + VMOVDQU Y4, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_4x5_loop + VZEROUPPER + +mulAvxTwo_4x5_end: + RET + +// func mulAvxTwo_4x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 59 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R10 + MOVQ 24(R9), R11 + MOVQ 48(R9), R12 + MOVQ 72(R9), R9 + MOVQ $0x0000000f, R13 + MOVQ R13, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R13 + +mulAvxTwo_4x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R10)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (R11)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (R12)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R9)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (SI)(R13*1) + VMOVDQU Y3, (DI)(R13*1) + VMOVDQU Y4, (R8)(R13*1) + VMOVDQU Y5, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_4x6_loop + VZEROUPPER + +mulAvxTwo_4x6_end: + RET + +// func mulAvxTwo_4x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 68 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x7_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), DX + MOVQ in_base+24(FP), R10 + MOVQ (R10), R11 + MOVQ 24(R10), R12 + MOVQ 48(R10), R13 + MOVQ 72(R10), R10 + MOVQ $0x0000000f, R14 + MOVQ R14, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R14 + +mulAvxTwo_4x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (R11)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (R12)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (R13)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R10)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (SI)(R14*1) + VMOVDQU Y3, (DI)(R14*1) + VMOVDQU Y4, (R8)(R14*1) + VMOVDQU Y5, (R9)(R14*1) + VMOVDQU Y6, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_4x7_loop + VZEROUPPER + +mulAvxTwo_4x7_end: + RET + +// func mulAvxTwo_4x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_4x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 77 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_4x8_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), R10 + MOVQ 168(DX), DX + MOVQ in_base+24(FP), R11 + MOVQ (R11), R12 + MOVQ 24(R11), R13 + MOVQ 48(R11), R14 + MOVQ 72(R11), R11 + MOVQ $0x0000000f, R15 + MOVQ R15, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R15 + +mulAvxTwo_4x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (R12)(R15*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (R13)(R15*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (R14)(R15*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R11)(R15*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (SI)(R15*1) + VMOVDQU Y3, (DI)(R15*1) + VMOVDQU Y4, (R8)(R15*1) + VMOVDQU Y5, (R9)(R15*1) + VMOVDQU Y6, (R10)(R15*1) + VMOVDQU Y7, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_4x8_loop + VZEROUPPER + +mulAvxTwo_4x8_end: + RET + +// func mulAvxTwo_5x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 14 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + MOVQ in_base+24(FP), CX + MOVQ (CX), BX + MOVQ 24(CX), BP + MOVQ 48(CX), SI + MOVQ 72(CX), DI + MOVQ 96(CX), CX + MOVQ $0x0000000f, R8 + MOVQ R8, X11 + VPBROADCASTB X11, Y11 + MOVQ start+72(FP), R8 + +mulAvxTwo_5x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BX)(R8*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y11, Y12, Y12 + VPAND Y11, Y13, Y13 + VPSHUFB Y12, Y1, Y12 + VPSHUFB Y13, Y2, Y13 + VPXOR Y12, Y13, Y12 + VPXOR Y12, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (BP)(R8*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y11, Y12, Y12 + VPAND Y11, Y13, Y13 + VPSHUFB Y12, Y3, Y12 + VPSHUFB Y13, Y4, Y13 + VPXOR Y12, Y13, Y12 + VPXOR Y12, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (SI)(R8*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y11, Y12, Y12 + VPAND Y11, Y13, Y13 + VPSHUFB Y12, Y5, Y12 + VPSHUFB Y13, Y6, Y13 + VPXOR Y12, Y13, Y12 + VPXOR Y12, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (DI)(R8*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y11, Y12, Y12 + VPAND Y11, Y13, Y13 + VPSHUFB Y12, Y7, Y12 + VPSHUFB Y13, Y8, Y13 + VPXOR Y12, Y13, Y12 + VPXOR Y12, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (CX)(R8*1), Y12 + VPSRLQ $0x04, Y12, Y13 + VPAND Y11, Y12, Y12 + VPAND Y11, Y13, Y13 + VPSHUFB Y12, Y9, Y12 + VPSHUFB Y13, Y10, Y13 + VPXOR Y12, Y13, Y12 + VPXOR Y12, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R8*1) + + // Prepare for next loop + ADDQ $0x20, R8 + DECQ AX + JNZ mulAvxTwo_5x1_loop + VZEROUPPER + +mulAvxTwo_5x1_end: + RET + +// func mulAvxTwo_5x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 27 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), BP + MOVQ $0x0000000f, R10 + MOVQ R10, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R10 + +mulAvxTwo_5x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R10*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R10*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R10*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R10*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (BP)(R10*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R10*1) + VMOVDQU Y1, (DX)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_5x2_loop + VZEROUPPER + +mulAvxTwo_5x2_end: + RET + +// func mulAvxTwo_5x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 38 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), R10 + MOVQ 96(SI), SI + MOVQ $0x0000000f, R11 + MOVQ R11, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R11 + +mulAvxTwo_5x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R11*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R11*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R11*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R10)(R11*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (SI)(R11*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (BP)(R11*1) + VMOVDQU Y2, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_5x3_loop + VZEROUPPER + +mulAvxTwo_5x3_end: + RET + +// func mulAvxTwo_5x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 49 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), R10 + MOVQ 72(DI), R11 + MOVQ 96(DI), DI + MOVQ $0x0000000f, R12 + MOVQ R12, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R12 + +mulAvxTwo_5x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R12*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R12*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (R10)(R12*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R11)(R12*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (DI)(R12*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (SI)(R12*1) + VMOVDQU Y3, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_5x4_loop + VZEROUPPER + +mulAvxTwo_5x4_end: + RET + +// func mulAvxTwo_5x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 60 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R10 + MOVQ 48(R8), R11 + MOVQ 72(R8), R12 + MOVQ 96(R8), R8 + MOVQ $0x0000000f, R13 + MOVQ R13, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R13 + +mulAvxTwo_5x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R10)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (R11)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R12)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R8)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (SI)(R13*1) + VMOVDQU Y3, (DI)(R13*1) + VMOVDQU Y4, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_5x5_loop + VZEROUPPER + +mulAvxTwo_5x5_end: + RET + +// func mulAvxTwo_5x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 71 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R10 + MOVQ 24(R9), R11 + MOVQ 48(R9), R12 + MOVQ 72(R9), R13 + MOVQ 96(R9), R9 + MOVQ $0x0000000f, R14 + MOVQ R14, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R14 + +mulAvxTwo_5x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R10)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (R11)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (R12)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R13)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R9)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (SI)(R14*1) + VMOVDQU Y3, (DI)(R14*1) + VMOVDQU Y4, (R8)(R14*1) + VMOVDQU Y5, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_5x6_loop + VZEROUPPER + +mulAvxTwo_5x6_end: + RET + +// func mulAvxTwo_5x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 82 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x7_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), R9 + MOVQ 144(DX), DX + MOVQ in_base+24(FP), R10 + MOVQ (R10), R11 + MOVQ 24(R10), R12 + MOVQ 48(R10), R13 + MOVQ 72(R10), R14 + MOVQ 96(R10), R10 + MOVQ $0x0000000f, R15 + MOVQ R15, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R15 + +mulAvxTwo_5x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (R11)(R15*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (R12)(R15*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (R13)(R15*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R14)(R15*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R10)(R15*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (SI)(R15*1) + VMOVDQU Y3, (DI)(R15*1) + VMOVDQU Y4, (R8)(R15*1) + VMOVDQU Y5, (R9)(R15*1) + VMOVDQU Y6, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_5x7_loop + VZEROUPPER + +mulAvxTwo_5x7_end: + RET + +// func mulAvxTwo_5x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_5x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 93 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_5x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), BX + MOVQ $0x0000000f, R9 + MOVQ R9, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R9 + +mulAvxTwo_5x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R9*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R9*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R9*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R9*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (BX)(R9*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R10 + VMOVDQU Y0, (R10)(R9*1) + MOVQ 24(DX), R10 + VMOVDQU Y1, (R10)(R9*1) + MOVQ 48(DX), R10 + VMOVDQU Y2, (R10)(R9*1) + MOVQ 72(DX), R10 + VMOVDQU Y3, (R10)(R9*1) + MOVQ 96(DX), R10 + VMOVDQU Y4, (R10)(R9*1) + MOVQ 120(DX), R10 + VMOVDQU Y5, (R10)(R9*1) + MOVQ 144(DX), R10 + VMOVDQU Y6, (R10)(R9*1) + MOVQ 168(DX), R10 + VMOVDQU Y7, (R10)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_5x8_loop + VZEROUPPER + +mulAvxTwo_5x8_end: + RET + +// func mulAvxTwo_6x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x1(SB), $0-88 + // Loading all tables to registers + // Full registers estimated 16 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + VMOVDQU (CX), Y1 + VMOVDQU 32(CX), Y2 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VMOVDQU 320(CX), Y11 + VMOVDQU 352(CX), Y12 + MOVQ in_base+24(FP), CX + MOVQ (CX), BX + MOVQ 24(CX), BP + MOVQ 48(CX), SI + MOVQ 72(CX), DI + MOVQ 96(CX), R8 + MOVQ 120(CX), CX + MOVQ $0x0000000f, R9 + MOVQ R9, X13 + VPBROADCASTB X13, Y13 + MOVQ start+72(FP), R9 + +mulAvxTwo_6x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BX)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y1, Y14 + VPSHUFB Y15, Y2, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (BP)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y3, Y14 + VPSHUFB Y15, Y4, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (SI)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y5, Y14 + VPSHUFB Y15, Y6, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (DI)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y7, Y14 + VPSHUFB Y15, Y8, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (R8)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y9, Y14 + VPSHUFB Y15, Y10, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Load and process 32 bytes from input 5 to 1 outputs + VMOVDQU (CX)(R9*1), Y14 + VPSRLQ $0x04, Y14, Y15 + VPAND Y13, Y14, Y14 + VPAND Y13, Y15, Y15 + VPSHUFB Y14, Y11, Y14 + VPSHUFB Y15, Y12, Y15 + VPXOR Y14, Y15, Y14 + VPXOR Y14, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R9*1) + + // Prepare for next loop + ADDQ $0x20, R9 + DECQ AX + JNZ mulAvxTwo_6x1_loop + VZEROUPPER + +mulAvxTwo_6x1_end: + RET + +// func mulAvxTwo_6x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 31 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), R10 + MOVQ 120(BP), BP + MOVQ $0x0000000f, R11 + MOVQ R11, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R11 + +mulAvxTwo_6x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (R10)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 5 to 2 outputs + VMOVDQU (BP)(R11*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 640(CX), Y3 + VMOVDQU 672(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 704(CX), Y3 + VMOVDQU 736(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R11*1) + VMOVDQU Y1, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_6x2_loop + VZEROUPPER + +mulAvxTwo_6x2_end: + RET + +// func mulAvxTwo_6x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 44 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), R10 + MOVQ 96(SI), R11 + MOVQ 120(SI), SI + MOVQ $0x0000000f, R12 + MOVQ R12, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R12 + +mulAvxTwo_6x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R10)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (R11)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 5 to 3 outputs + VMOVDQU (SI)(R12*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 960(CX), Y4 + VMOVDQU 992(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1024(CX), Y4 + VMOVDQU 1056(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1088(CX), Y4 + VMOVDQU 1120(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (BP)(R12*1) + VMOVDQU Y2, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_6x3_loop + VZEROUPPER + +mulAvxTwo_6x3_end: + RET + +// func mulAvxTwo_6x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 57 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), R10 + MOVQ 72(DI), R11 + MOVQ 96(DI), R12 + MOVQ 120(DI), DI + MOVQ $0x0000000f, R13 + MOVQ R13, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R13 + +mulAvxTwo_6x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (R10)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R11)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (R12)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 5 to 4 outputs + VMOVDQU (DI)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1280(CX), Y5 + VMOVDQU 1312(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1344(CX), Y5 + VMOVDQU 1376(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1408(CX), Y5 + VMOVDQU 1440(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1472(CX), Y5 + VMOVDQU 1504(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (SI)(R13*1) + VMOVDQU Y3, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_6x4_loop + VZEROUPPER + +mulAvxTwo_6x4_end: + RET + +// func mulAvxTwo_6x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 70 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R10 + MOVQ 48(R8), R11 + MOVQ 72(R8), R12 + MOVQ 96(R8), R13 + MOVQ 120(R8), R8 + MOVQ $0x0000000f, R14 + MOVQ R14, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R14 + +mulAvxTwo_6x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R10)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (R11)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R12)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R13)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 5 to 5 outputs + VMOVDQU (R8)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1600(CX), Y6 + VMOVDQU 1632(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1664(CX), Y6 + VMOVDQU 1696(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1728(CX), Y6 + VMOVDQU 1760(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1792(CX), Y6 + VMOVDQU 1824(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1856(CX), Y6 + VMOVDQU 1888(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (SI)(R14*1) + VMOVDQU Y3, (DI)(R14*1) + VMOVDQU Y4, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_6x5_loop + VZEROUPPER + +mulAvxTwo_6x5_end: + RET + +// func mulAvxTwo_6x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 83 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x6_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), R8 + MOVQ 120(DX), DX + MOVQ in_base+24(FP), R9 + MOVQ (R9), R10 + MOVQ 24(R9), R11 + MOVQ 48(R9), R12 + MOVQ 72(R9), R13 + MOVQ 96(R9), R14 + MOVQ 120(R9), R9 + MOVQ $0x0000000f, R15 + MOVQ R15, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R15 + +mulAvxTwo_6x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (R10)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (R11)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (R12)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R13)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R14)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 5 to 6 outputs + VMOVDQU (R9)(R15*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1920(CX), Y7 + VMOVDQU 1952(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1984(CX), Y7 + VMOVDQU 2016(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2048(CX), Y7 + VMOVDQU 2080(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2112(CX), Y7 + VMOVDQU 2144(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2176(CX), Y7 + VMOVDQU 2208(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2240(CX), Y7 + VMOVDQU 2272(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (SI)(R15*1) + VMOVDQU Y3, (DI)(R15*1) + VMOVDQU Y4, (R8)(R15*1) + VMOVDQU Y5, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_6x6_loop + VZEROUPPER + +mulAvxTwo_6x6_end: + RET + +// func mulAvxTwo_6x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 96 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x7_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), BX + MOVQ $0x0000000f, R10 + MOVQ R10, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R10 + +mulAvxTwo_6x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (BP)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (SI)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (DI)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R8)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R9)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 5 to 7 outputs + VMOVDQU (BX)(R10*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2240(CX), Y8 + VMOVDQU 2272(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2304(CX), Y8 + VMOVDQU 2336(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2368(CX), Y8 + VMOVDQU 2400(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2432(CX), Y8 + VMOVDQU 2464(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2496(CX), Y8 + VMOVDQU 2528(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2560(CX), Y8 + VMOVDQU 2592(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2624(CX), Y8 + VMOVDQU 2656(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + MOVQ (DX), R11 + VMOVDQU Y0, (R11)(R10*1) + MOVQ 24(DX), R11 + VMOVDQU Y1, (R11)(R10*1) + MOVQ 48(DX), R11 + VMOVDQU Y2, (R11)(R10*1) + MOVQ 72(DX), R11 + VMOVDQU Y3, (R11)(R10*1) + MOVQ 96(DX), R11 + VMOVDQU Y4, (R11)(R10*1) + MOVQ 120(DX), R11 + VMOVDQU Y5, (R11)(R10*1) + MOVQ 144(DX), R11 + VMOVDQU Y6, (R11)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_6x7_loop + VZEROUPPER + +mulAvxTwo_6x7_end: + RET + +// func mulAvxTwo_6x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_6x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 109 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_6x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), BX + MOVQ $0x0000000f, R10 + MOVQ R10, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R10 + +mulAvxTwo_6x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (R9)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 5 to 8 outputs + VMOVDQU (BX)(R10*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2560(CX), Y9 + VMOVDQU 2592(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2624(CX), Y9 + VMOVDQU 2656(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2688(CX), Y9 + VMOVDQU 2720(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2752(CX), Y9 + VMOVDQU 2784(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2816(CX), Y9 + VMOVDQU 2848(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2880(CX), Y9 + VMOVDQU 2912(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2944(CX), Y9 + VMOVDQU 2976(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3008(CX), Y9 + VMOVDQU 3040(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R11 + VMOVDQU Y0, (R11)(R10*1) + MOVQ 24(DX), R11 + VMOVDQU Y1, (R11)(R10*1) + MOVQ 48(DX), R11 + VMOVDQU Y2, (R11)(R10*1) + MOVQ 72(DX), R11 + VMOVDQU Y3, (R11)(R10*1) + MOVQ 96(DX), R11 + VMOVDQU Y4, (R11)(R10*1) + MOVQ 120(DX), R11 + VMOVDQU Y5, (R11)(R10*1) + MOVQ 144(DX), R11 + VMOVDQU Y6, (R11)(R10*1) + MOVQ 168(DX), R11 + VMOVDQU Y7, (R11)(R10*1) + + // Prepare for next loop + ADDQ $0x20, R10 + DECQ AX + JNZ mulAvxTwo_6x8_loop + VZEROUPPER + +mulAvxTwo_6x8_end: + RET + +// func mulAvxTwo_7x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x1(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 18 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), BX + MOVQ $0x0000000f, R11 + MOVQ R11, X1 + VPBROADCASTB X1, Y1 + MOVQ start+72(FP), R11 + +mulAvxTwo_7x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BP)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (SI)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 64(CX), Y2 + VMOVDQU 96(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (DI)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 128(CX), Y2 + VMOVDQU 160(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (R8)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 192(CX), Y2 + VMOVDQU 224(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (R9)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 256(CX), Y2 + VMOVDQU 288(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 5 to 1 outputs + VMOVDQU (R10)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 320(CX), Y2 + VMOVDQU 352(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 6 to 1 outputs + VMOVDQU (BX)(R11*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 384(CX), Y2 + VMOVDQU 416(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_7x1_loop + VZEROUPPER + +mulAvxTwo_7x1_end: + RET + +// func mulAvxTwo_7x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 35 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), R10 + MOVQ 120(BP), R11 + MOVQ 144(BP), BP + MOVQ $0x0000000f, R12 + MOVQ R12, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R12 + +mulAvxTwo_7x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (R10)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 5 to 2 outputs + VMOVDQU (R11)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 640(CX), Y3 + VMOVDQU 672(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 704(CX), Y3 + VMOVDQU 736(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 6 to 2 outputs + VMOVDQU (BP)(R12*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 768(CX), Y3 + VMOVDQU 800(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 832(CX), Y3 + VMOVDQU 864(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R12*1) + VMOVDQU Y1, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_7x2_loop + VZEROUPPER + +mulAvxTwo_7x2_end: + RET + +// func mulAvxTwo_7x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 50 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), R10 + MOVQ 96(SI), R11 + MOVQ 120(SI), R12 + MOVQ 144(SI), SI + MOVQ $0x0000000f, R13 + MOVQ R13, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R13 + +mulAvxTwo_7x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R10)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (R11)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 5 to 3 outputs + VMOVDQU (R12)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 960(CX), Y4 + VMOVDQU 992(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1024(CX), Y4 + VMOVDQU 1056(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1088(CX), Y4 + VMOVDQU 1120(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 6 to 3 outputs + VMOVDQU (SI)(R13*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1152(CX), Y4 + VMOVDQU 1184(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1216(CX), Y4 + VMOVDQU 1248(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1280(CX), Y4 + VMOVDQU 1312(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (BP)(R13*1) + VMOVDQU Y2, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_7x3_loop + VZEROUPPER + +mulAvxTwo_7x3_end: + RET + +// func mulAvxTwo_7x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 65 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), R10 + MOVQ 72(DI), R11 + MOVQ 96(DI), R12 + MOVQ 120(DI), R13 + MOVQ 144(DI), DI + MOVQ $0x0000000f, R14 + MOVQ R14, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R14 + +mulAvxTwo_7x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (R10)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R11)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (R12)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 5 to 4 outputs + VMOVDQU (R13)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1280(CX), Y5 + VMOVDQU 1312(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1344(CX), Y5 + VMOVDQU 1376(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1408(CX), Y5 + VMOVDQU 1440(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1472(CX), Y5 + VMOVDQU 1504(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 6 to 4 outputs + VMOVDQU (DI)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1536(CX), Y5 + VMOVDQU 1568(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1600(CX), Y5 + VMOVDQU 1632(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1664(CX), Y5 + VMOVDQU 1696(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1728(CX), Y5 + VMOVDQU 1760(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (SI)(R14*1) + VMOVDQU Y3, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_7x4_loop + VZEROUPPER + +mulAvxTwo_7x4_end: + RET + +// func mulAvxTwo_7x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 80 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x5_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DI + MOVQ 96(DX), DX + MOVQ in_base+24(FP), R8 + MOVQ (R8), R9 + MOVQ 24(R8), R10 + MOVQ 48(R8), R11 + MOVQ 72(R8), R12 + MOVQ 96(R8), R13 + MOVQ 120(R8), R14 + MOVQ 144(R8), R8 + MOVQ $0x0000000f, R15 + MOVQ R15, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R15 + +mulAvxTwo_7x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (R9)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (R10)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (R11)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R12)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R13)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 5 to 5 outputs + VMOVDQU (R14)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1600(CX), Y6 + VMOVDQU 1632(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1664(CX), Y6 + VMOVDQU 1696(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1728(CX), Y6 + VMOVDQU 1760(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1792(CX), Y6 + VMOVDQU 1824(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1856(CX), Y6 + VMOVDQU 1888(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 6 to 5 outputs + VMOVDQU (R8)(R15*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1920(CX), Y6 + VMOVDQU 1952(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1984(CX), Y6 + VMOVDQU 2016(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2048(CX), Y6 + VMOVDQU 2080(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2112(CX), Y6 + VMOVDQU 2144(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2176(CX), Y6 + VMOVDQU 2208(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (SI)(R15*1) + VMOVDQU Y3, (DI)(R15*1) + VMOVDQU Y4, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_7x5_loop + VZEROUPPER + +mulAvxTwo_7x5_end: + RET + +// func mulAvxTwo_7x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 95 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x6_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), BX + MOVQ $0x0000000f, R11 + MOVQ R11, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R11 + +mulAvxTwo_7x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (BP)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (SI)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (DI)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R8)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R9)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 5 to 6 outputs + VMOVDQU (R10)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1920(CX), Y7 + VMOVDQU 1952(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1984(CX), Y7 + VMOVDQU 2016(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2048(CX), Y7 + VMOVDQU 2080(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2112(CX), Y7 + VMOVDQU 2144(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2176(CX), Y7 + VMOVDQU 2208(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2240(CX), Y7 + VMOVDQU 2272(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 6 to 6 outputs + VMOVDQU (BX)(R11*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2304(CX), Y7 + VMOVDQU 2336(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2368(CX), Y7 + VMOVDQU 2400(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2432(CX), Y7 + VMOVDQU 2464(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2496(CX), Y7 + VMOVDQU 2528(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2560(CX), Y7 + VMOVDQU 2592(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2624(CX), Y7 + VMOVDQU 2656(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + MOVQ (DX), R12 + VMOVDQU Y0, (R12)(R11*1) + MOVQ 24(DX), R12 + VMOVDQU Y1, (R12)(R11*1) + MOVQ 48(DX), R12 + VMOVDQU Y2, (R12)(R11*1) + MOVQ 72(DX), R12 + VMOVDQU Y3, (R12)(R11*1) + MOVQ 96(DX), R12 + VMOVDQU Y4, (R12)(R11*1) + MOVQ 120(DX), R12 + VMOVDQU Y5, (R12)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_7x6_loop + VZEROUPPER + +mulAvxTwo_7x6_end: + RET + +// func mulAvxTwo_7x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 110 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x7_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), BX + MOVQ $0x0000000f, R11 + MOVQ R11, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R11 + +mulAvxTwo_7x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (BP)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (SI)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (DI)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R8)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R9)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 5 to 7 outputs + VMOVDQU (R10)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2240(CX), Y8 + VMOVDQU 2272(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2304(CX), Y8 + VMOVDQU 2336(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2368(CX), Y8 + VMOVDQU 2400(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2432(CX), Y8 + VMOVDQU 2464(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2496(CX), Y8 + VMOVDQU 2528(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2560(CX), Y8 + VMOVDQU 2592(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2624(CX), Y8 + VMOVDQU 2656(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 6 to 7 outputs + VMOVDQU (BX)(R11*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2688(CX), Y8 + VMOVDQU 2720(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2752(CX), Y8 + VMOVDQU 2784(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2816(CX), Y8 + VMOVDQU 2848(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2880(CX), Y8 + VMOVDQU 2912(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2944(CX), Y8 + VMOVDQU 2976(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3008(CX), Y8 + VMOVDQU 3040(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3072(CX), Y8 + VMOVDQU 3104(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + MOVQ (DX), R12 + VMOVDQU Y0, (R12)(R11*1) + MOVQ 24(DX), R12 + VMOVDQU Y1, (R12)(R11*1) + MOVQ 48(DX), R12 + VMOVDQU Y2, (R12)(R11*1) + MOVQ 72(DX), R12 + VMOVDQU Y3, (R12)(R11*1) + MOVQ 96(DX), R12 + VMOVDQU Y4, (R12)(R11*1) + MOVQ 120(DX), R12 + VMOVDQU Y5, (R12)(R11*1) + MOVQ 144(DX), R12 + VMOVDQU Y6, (R12)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_7x7_loop + VZEROUPPER + +mulAvxTwo_7x7_end: + RET + +// func mulAvxTwo_7x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_7x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 125 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_7x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), BX + MOVQ $0x0000000f, R11 + MOVQ R11, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R11 + +mulAvxTwo_7x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (R9)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 5 to 8 outputs + VMOVDQU (R10)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2560(CX), Y9 + VMOVDQU 2592(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2624(CX), Y9 + VMOVDQU 2656(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2688(CX), Y9 + VMOVDQU 2720(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2752(CX), Y9 + VMOVDQU 2784(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2816(CX), Y9 + VMOVDQU 2848(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2880(CX), Y9 + VMOVDQU 2912(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2944(CX), Y9 + VMOVDQU 2976(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3008(CX), Y9 + VMOVDQU 3040(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 6 to 8 outputs + VMOVDQU (BX)(R11*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3072(CX), Y9 + VMOVDQU 3104(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3136(CX), Y9 + VMOVDQU 3168(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3200(CX), Y9 + VMOVDQU 3232(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3264(CX), Y9 + VMOVDQU 3296(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3328(CX), Y9 + VMOVDQU 3360(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3392(CX), Y9 + VMOVDQU 3424(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3456(CX), Y9 + VMOVDQU 3488(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3520(CX), Y9 + VMOVDQU 3552(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R12 + VMOVDQU Y0, (R12)(R11*1) + MOVQ 24(DX), R12 + VMOVDQU Y1, (R12)(R11*1) + MOVQ 48(DX), R12 + VMOVDQU Y2, (R12)(R11*1) + MOVQ 72(DX), R12 + VMOVDQU Y3, (R12)(R11*1) + MOVQ 96(DX), R12 + VMOVDQU Y4, (R12)(R11*1) + MOVQ 120(DX), R12 + VMOVDQU Y5, (R12)(R11*1) + MOVQ 144(DX), R12 + VMOVDQU Y6, (R12)(R11*1) + MOVQ 168(DX), R12 + VMOVDQU Y7, (R12)(R11*1) + + // Prepare for next loop + ADDQ $0x20, R11 + DECQ AX + JNZ mulAvxTwo_7x8_loop + VZEROUPPER + +mulAvxTwo_7x8_end: + RET + +// func mulAvxTwo_8x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x1(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 20 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), BX + MOVQ $0x0000000f, R12 + MOVQ R12, X1 + VPBROADCASTB X1, Y1 + MOVQ start+72(FP), R12 + +mulAvxTwo_8x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BP)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (SI)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 64(CX), Y2 + VMOVDQU 96(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (DI)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 128(CX), Y2 + VMOVDQU 160(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (R8)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 192(CX), Y2 + VMOVDQU 224(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (R9)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 256(CX), Y2 + VMOVDQU 288(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 5 to 1 outputs + VMOVDQU (R10)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 320(CX), Y2 + VMOVDQU 352(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 6 to 1 outputs + VMOVDQU (R11)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 384(CX), Y2 + VMOVDQU 416(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 7 to 1 outputs + VMOVDQU (BX)(R12*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 448(CX), Y2 + VMOVDQU 480(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_8x1_loop + VZEROUPPER + +mulAvxTwo_8x1_end: + RET + +// func mulAvxTwo_8x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 39 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), R10 + MOVQ 120(BP), R11 + MOVQ 144(BP), R12 + MOVQ 168(BP), BP + MOVQ $0x0000000f, R13 + MOVQ R13, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R13 + +mulAvxTwo_8x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (R10)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 5 to 2 outputs + VMOVDQU (R11)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 640(CX), Y3 + VMOVDQU 672(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 704(CX), Y3 + VMOVDQU 736(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 6 to 2 outputs + VMOVDQU (R12)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 768(CX), Y3 + VMOVDQU 800(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 832(CX), Y3 + VMOVDQU 864(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 7 to 2 outputs + VMOVDQU (BP)(R13*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 896(CX), Y3 + VMOVDQU 928(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 960(CX), Y3 + VMOVDQU 992(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R13*1) + VMOVDQU Y1, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_8x2_loop + VZEROUPPER + +mulAvxTwo_8x2_end: + RET + +// func mulAvxTwo_8x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 56 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), R10 + MOVQ 96(SI), R11 + MOVQ 120(SI), R12 + MOVQ 144(SI), R13 + MOVQ 168(SI), SI + MOVQ $0x0000000f, R14 + MOVQ R14, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R14 + +mulAvxTwo_8x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R10)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (R11)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 5 to 3 outputs + VMOVDQU (R12)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 960(CX), Y4 + VMOVDQU 992(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1024(CX), Y4 + VMOVDQU 1056(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1088(CX), Y4 + VMOVDQU 1120(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 6 to 3 outputs + VMOVDQU (R13)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1152(CX), Y4 + VMOVDQU 1184(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1216(CX), Y4 + VMOVDQU 1248(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1280(CX), Y4 + VMOVDQU 1312(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 7 to 3 outputs + VMOVDQU (SI)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1344(CX), Y4 + VMOVDQU 1376(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1408(CX), Y4 + VMOVDQU 1440(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1472(CX), Y4 + VMOVDQU 1504(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (BP)(R14*1) + VMOVDQU Y2, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_8x3_loop + VZEROUPPER + +mulAvxTwo_8x3_end: + RET + +// func mulAvxTwo_8x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 73 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x4_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), SI + MOVQ 72(DX), DX + MOVQ in_base+24(FP), DI + MOVQ (DI), R8 + MOVQ 24(DI), R9 + MOVQ 48(DI), R10 + MOVQ 72(DI), R11 + MOVQ 96(DI), R12 + MOVQ 120(DI), R13 + MOVQ 144(DI), R14 + MOVQ 168(DI), DI + MOVQ $0x0000000f, R15 + MOVQ R15, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R15 + +mulAvxTwo_8x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (R8)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (R9)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (R10)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R11)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (R12)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 5 to 4 outputs + VMOVDQU (R13)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1280(CX), Y5 + VMOVDQU 1312(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1344(CX), Y5 + VMOVDQU 1376(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1408(CX), Y5 + VMOVDQU 1440(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1472(CX), Y5 + VMOVDQU 1504(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 6 to 4 outputs + VMOVDQU (R14)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1536(CX), Y5 + VMOVDQU 1568(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1600(CX), Y5 + VMOVDQU 1632(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1664(CX), Y5 + VMOVDQU 1696(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1728(CX), Y5 + VMOVDQU 1760(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 7 to 4 outputs + VMOVDQU (DI)(R15*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1792(CX), Y5 + VMOVDQU 1824(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1856(CX), Y5 + VMOVDQU 1888(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1920(CX), Y5 + VMOVDQU 1952(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1984(CX), Y5 + VMOVDQU 2016(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (SI)(R15*1) + VMOVDQU Y3, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_8x4_loop + VZEROUPPER + +mulAvxTwo_8x4_end: + RET + +// func mulAvxTwo_8x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 90 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x5_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), BX + MOVQ $0x0000000f, R12 + MOVQ R12, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R12 + +mulAvxTwo_8x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (BP)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (SI)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (DI)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R8)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R9)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 5 to 5 outputs + VMOVDQU (R10)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1600(CX), Y6 + VMOVDQU 1632(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1664(CX), Y6 + VMOVDQU 1696(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1728(CX), Y6 + VMOVDQU 1760(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1792(CX), Y6 + VMOVDQU 1824(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1856(CX), Y6 + VMOVDQU 1888(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 6 to 5 outputs + VMOVDQU (R11)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1920(CX), Y6 + VMOVDQU 1952(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1984(CX), Y6 + VMOVDQU 2016(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2048(CX), Y6 + VMOVDQU 2080(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2112(CX), Y6 + VMOVDQU 2144(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2176(CX), Y6 + VMOVDQU 2208(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 7 to 5 outputs + VMOVDQU (BX)(R12*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2240(CX), Y6 + VMOVDQU 2272(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2304(CX), Y6 + VMOVDQU 2336(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2368(CX), Y6 + VMOVDQU 2400(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2432(CX), Y6 + VMOVDQU 2464(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2496(CX), Y6 + VMOVDQU 2528(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + MOVQ (DX), R13 + VMOVDQU Y0, (R13)(R12*1) + MOVQ 24(DX), R13 + VMOVDQU Y1, (R13)(R12*1) + MOVQ 48(DX), R13 + VMOVDQU Y2, (R13)(R12*1) + MOVQ 72(DX), R13 + VMOVDQU Y3, (R13)(R12*1) + MOVQ 96(DX), R13 + VMOVDQU Y4, (R13)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_8x5_loop + VZEROUPPER + +mulAvxTwo_8x5_end: + RET + +// func mulAvxTwo_8x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 107 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x6_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), BX + MOVQ $0x0000000f, R12 + MOVQ R12, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R12 + +mulAvxTwo_8x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (BP)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (SI)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (DI)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R8)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R9)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 5 to 6 outputs + VMOVDQU (R10)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1920(CX), Y7 + VMOVDQU 1952(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1984(CX), Y7 + VMOVDQU 2016(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2048(CX), Y7 + VMOVDQU 2080(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2112(CX), Y7 + VMOVDQU 2144(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2176(CX), Y7 + VMOVDQU 2208(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2240(CX), Y7 + VMOVDQU 2272(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 6 to 6 outputs + VMOVDQU (R11)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2304(CX), Y7 + VMOVDQU 2336(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2368(CX), Y7 + VMOVDQU 2400(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2432(CX), Y7 + VMOVDQU 2464(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2496(CX), Y7 + VMOVDQU 2528(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2560(CX), Y7 + VMOVDQU 2592(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2624(CX), Y7 + VMOVDQU 2656(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 7 to 6 outputs + VMOVDQU (BX)(R12*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2688(CX), Y7 + VMOVDQU 2720(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2752(CX), Y7 + VMOVDQU 2784(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2816(CX), Y7 + VMOVDQU 2848(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2880(CX), Y7 + VMOVDQU 2912(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2944(CX), Y7 + VMOVDQU 2976(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3008(CX), Y7 + VMOVDQU 3040(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + MOVQ (DX), R13 + VMOVDQU Y0, (R13)(R12*1) + MOVQ 24(DX), R13 + VMOVDQU Y1, (R13)(R12*1) + MOVQ 48(DX), R13 + VMOVDQU Y2, (R13)(R12*1) + MOVQ 72(DX), R13 + VMOVDQU Y3, (R13)(R12*1) + MOVQ 96(DX), R13 + VMOVDQU Y4, (R13)(R12*1) + MOVQ 120(DX), R13 + VMOVDQU Y5, (R13)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_8x6_loop + VZEROUPPER + +mulAvxTwo_8x6_end: + RET + +// func mulAvxTwo_8x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 124 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x7_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), BX + MOVQ $0x0000000f, R12 + MOVQ R12, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R12 + +mulAvxTwo_8x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (BP)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (SI)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (DI)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R8)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R9)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 5 to 7 outputs + VMOVDQU (R10)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2240(CX), Y8 + VMOVDQU 2272(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2304(CX), Y8 + VMOVDQU 2336(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2368(CX), Y8 + VMOVDQU 2400(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2432(CX), Y8 + VMOVDQU 2464(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2496(CX), Y8 + VMOVDQU 2528(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2560(CX), Y8 + VMOVDQU 2592(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2624(CX), Y8 + VMOVDQU 2656(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 6 to 7 outputs + VMOVDQU (R11)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2688(CX), Y8 + VMOVDQU 2720(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2752(CX), Y8 + VMOVDQU 2784(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2816(CX), Y8 + VMOVDQU 2848(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2880(CX), Y8 + VMOVDQU 2912(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2944(CX), Y8 + VMOVDQU 2976(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3008(CX), Y8 + VMOVDQU 3040(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3072(CX), Y8 + VMOVDQU 3104(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 7 to 7 outputs + VMOVDQU (BX)(R12*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 3136(CX), Y8 + VMOVDQU 3168(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 3200(CX), Y8 + VMOVDQU 3232(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 3264(CX), Y8 + VMOVDQU 3296(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 3328(CX), Y8 + VMOVDQU 3360(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 3392(CX), Y8 + VMOVDQU 3424(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3456(CX), Y8 + VMOVDQU 3488(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3520(CX), Y8 + VMOVDQU 3552(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + MOVQ (DX), R13 + VMOVDQU Y0, (R13)(R12*1) + MOVQ 24(DX), R13 + VMOVDQU Y1, (R13)(R12*1) + MOVQ 48(DX), R13 + VMOVDQU Y2, (R13)(R12*1) + MOVQ 72(DX), R13 + VMOVDQU Y3, (R13)(R12*1) + MOVQ 96(DX), R13 + VMOVDQU Y4, (R13)(R12*1) + MOVQ 120(DX), R13 + VMOVDQU Y5, (R13)(R12*1) + MOVQ 144(DX), R13 + VMOVDQU Y6, (R13)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_8x7_loop + VZEROUPPER + +mulAvxTwo_8x7_end: + RET + +// func mulAvxTwo_8x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_8x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 141 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_8x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), BX + MOVQ $0x0000000f, R12 + MOVQ R12, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R12 + +mulAvxTwo_8x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (R9)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 5 to 8 outputs + VMOVDQU (R10)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2560(CX), Y9 + VMOVDQU 2592(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2624(CX), Y9 + VMOVDQU 2656(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2688(CX), Y9 + VMOVDQU 2720(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2752(CX), Y9 + VMOVDQU 2784(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2816(CX), Y9 + VMOVDQU 2848(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2880(CX), Y9 + VMOVDQU 2912(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2944(CX), Y9 + VMOVDQU 2976(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3008(CX), Y9 + VMOVDQU 3040(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 6 to 8 outputs + VMOVDQU (R11)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3072(CX), Y9 + VMOVDQU 3104(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3136(CX), Y9 + VMOVDQU 3168(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3200(CX), Y9 + VMOVDQU 3232(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3264(CX), Y9 + VMOVDQU 3296(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3328(CX), Y9 + VMOVDQU 3360(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3392(CX), Y9 + VMOVDQU 3424(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3456(CX), Y9 + VMOVDQU 3488(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3520(CX), Y9 + VMOVDQU 3552(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 7 to 8 outputs + VMOVDQU (BX)(R12*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3584(CX), Y9 + VMOVDQU 3616(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3648(CX), Y9 + VMOVDQU 3680(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3712(CX), Y9 + VMOVDQU 3744(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3776(CX), Y9 + VMOVDQU 3808(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3840(CX), Y9 + VMOVDQU 3872(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3904(CX), Y9 + VMOVDQU 3936(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3968(CX), Y9 + VMOVDQU 4000(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 4032(CX), Y9 + VMOVDQU 4064(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R13 + VMOVDQU Y0, (R13)(R12*1) + MOVQ 24(DX), R13 + VMOVDQU Y1, (R13)(R12*1) + MOVQ 48(DX), R13 + VMOVDQU Y2, (R13)(R12*1) + MOVQ 72(DX), R13 + VMOVDQU Y3, (R13)(R12*1) + MOVQ 96(DX), R13 + VMOVDQU Y4, (R13)(R12*1) + MOVQ 120(DX), R13 + VMOVDQU Y5, (R13)(R12*1) + MOVQ 144(DX), R13 + VMOVDQU Y6, (R13)(R12*1) + MOVQ 168(DX), R13 + VMOVDQU Y7, (R13)(R12*1) + + // Prepare for next loop + ADDQ $0x20, R12 + DECQ AX + JNZ mulAvxTwo_8x8_loop + VZEROUPPER + +mulAvxTwo_8x8_end: + RET + +// func mulAvxTwo_9x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x1(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 22 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X1 + VPBROADCASTB X1, Y1 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BP)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (SI)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 64(CX), Y2 + VMOVDQU 96(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (DI)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 128(CX), Y2 + VMOVDQU 160(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (R8)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 192(CX), Y2 + VMOVDQU 224(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (R9)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 256(CX), Y2 + VMOVDQU 288(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 5 to 1 outputs + VMOVDQU (R10)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 320(CX), Y2 + VMOVDQU 352(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 6 to 1 outputs + VMOVDQU (R11)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 384(CX), Y2 + VMOVDQU 416(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 7 to 1 outputs + VMOVDQU (R12)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 448(CX), Y2 + VMOVDQU 480(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 8 to 1 outputs + VMOVDQU (BX)(R13*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 512(CX), Y2 + VMOVDQU 544(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x1_loop + VZEROUPPER + +mulAvxTwo_9x1_end: + RET + +// func mulAvxTwo_9x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 43 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), R10 + MOVQ 120(BP), R11 + MOVQ 144(BP), R12 + MOVQ 168(BP), R13 + MOVQ 192(BP), BP + MOVQ $0x0000000f, R14 + MOVQ R14, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R14 + +mulAvxTwo_9x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (R10)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 5 to 2 outputs + VMOVDQU (R11)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 640(CX), Y3 + VMOVDQU 672(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 704(CX), Y3 + VMOVDQU 736(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 6 to 2 outputs + VMOVDQU (R12)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 768(CX), Y3 + VMOVDQU 800(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 832(CX), Y3 + VMOVDQU 864(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 7 to 2 outputs + VMOVDQU (R13)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 896(CX), Y3 + VMOVDQU 928(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 960(CX), Y3 + VMOVDQU 992(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 8 to 2 outputs + VMOVDQU (BP)(R14*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 1024(CX), Y3 + VMOVDQU 1056(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 1088(CX), Y3 + VMOVDQU 1120(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R14*1) + VMOVDQU Y1, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_9x2_loop + VZEROUPPER + +mulAvxTwo_9x2_end: + RET + +// func mulAvxTwo_9x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 62 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x3_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), BP + MOVQ 48(DX), DX + MOVQ in_base+24(FP), SI + MOVQ (SI), DI + MOVQ 24(SI), R8 + MOVQ 48(SI), R9 + MOVQ 72(SI), R10 + MOVQ 96(SI), R11 + MOVQ 120(SI), R12 + MOVQ 144(SI), R13 + MOVQ 168(SI), R14 + MOVQ 192(SI), SI + MOVQ $0x0000000f, R15 + MOVQ R15, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R15 + +mulAvxTwo_9x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (DI)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (R8)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (R9)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R10)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (R11)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 5 to 3 outputs + VMOVDQU (R12)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 960(CX), Y4 + VMOVDQU 992(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1024(CX), Y4 + VMOVDQU 1056(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1088(CX), Y4 + VMOVDQU 1120(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 6 to 3 outputs + VMOVDQU (R13)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1152(CX), Y4 + VMOVDQU 1184(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1216(CX), Y4 + VMOVDQU 1248(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1280(CX), Y4 + VMOVDQU 1312(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 7 to 3 outputs + VMOVDQU (R14)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1344(CX), Y4 + VMOVDQU 1376(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1408(CX), Y4 + VMOVDQU 1440(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1472(CX), Y4 + VMOVDQU 1504(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 8 to 3 outputs + VMOVDQU (SI)(R15*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1536(CX), Y4 + VMOVDQU 1568(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1600(CX), Y4 + VMOVDQU 1632(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1664(CX), Y4 + VMOVDQU 1696(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (BP)(R15*1) + VMOVDQU Y2, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_9x3_loop + VZEROUPPER + +mulAvxTwo_9x3_end: + RET + +// func mulAvxTwo_9x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 81 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x4_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (BP)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (SI)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (DI)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R8)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (R9)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 5 to 4 outputs + VMOVDQU (R10)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1280(CX), Y5 + VMOVDQU 1312(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1344(CX), Y5 + VMOVDQU 1376(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1408(CX), Y5 + VMOVDQU 1440(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1472(CX), Y5 + VMOVDQU 1504(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 6 to 4 outputs + VMOVDQU (R11)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1536(CX), Y5 + VMOVDQU 1568(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1600(CX), Y5 + VMOVDQU 1632(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1664(CX), Y5 + VMOVDQU 1696(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1728(CX), Y5 + VMOVDQU 1760(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 7 to 4 outputs + VMOVDQU (R12)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1792(CX), Y5 + VMOVDQU 1824(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1856(CX), Y5 + VMOVDQU 1888(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1920(CX), Y5 + VMOVDQU 1952(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1984(CX), Y5 + VMOVDQU 2016(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 8 to 4 outputs + VMOVDQU (BX)(R13*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 2048(CX), Y5 + VMOVDQU 2080(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 2112(CX), Y5 + VMOVDQU 2144(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 2176(CX), Y5 + VMOVDQU 2208(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 2240(CX), Y5 + VMOVDQU 2272(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + MOVQ (DX), R14 + VMOVDQU Y0, (R14)(R13*1) + MOVQ 24(DX), R14 + VMOVDQU Y1, (R14)(R13*1) + MOVQ 48(DX), R14 + VMOVDQU Y2, (R14)(R13*1) + MOVQ 72(DX), R14 + VMOVDQU Y3, (R14)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x4_loop + VZEROUPPER + +mulAvxTwo_9x4_end: + RET + +// func mulAvxTwo_9x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 100 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x5_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (BP)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (SI)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (DI)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R8)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R9)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 5 to 5 outputs + VMOVDQU (R10)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1600(CX), Y6 + VMOVDQU 1632(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1664(CX), Y6 + VMOVDQU 1696(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1728(CX), Y6 + VMOVDQU 1760(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1792(CX), Y6 + VMOVDQU 1824(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1856(CX), Y6 + VMOVDQU 1888(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 6 to 5 outputs + VMOVDQU (R11)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1920(CX), Y6 + VMOVDQU 1952(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1984(CX), Y6 + VMOVDQU 2016(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2048(CX), Y6 + VMOVDQU 2080(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2112(CX), Y6 + VMOVDQU 2144(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2176(CX), Y6 + VMOVDQU 2208(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 7 to 5 outputs + VMOVDQU (R12)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2240(CX), Y6 + VMOVDQU 2272(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2304(CX), Y6 + VMOVDQU 2336(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2368(CX), Y6 + VMOVDQU 2400(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2432(CX), Y6 + VMOVDQU 2464(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2496(CX), Y6 + VMOVDQU 2528(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 8 to 5 outputs + VMOVDQU (BX)(R13*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2560(CX), Y6 + VMOVDQU 2592(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2624(CX), Y6 + VMOVDQU 2656(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2688(CX), Y6 + VMOVDQU 2720(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2752(CX), Y6 + VMOVDQU 2784(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2816(CX), Y6 + VMOVDQU 2848(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + MOVQ (DX), R14 + VMOVDQU Y0, (R14)(R13*1) + MOVQ 24(DX), R14 + VMOVDQU Y1, (R14)(R13*1) + MOVQ 48(DX), R14 + VMOVDQU Y2, (R14)(R13*1) + MOVQ 72(DX), R14 + VMOVDQU Y3, (R14)(R13*1) + MOVQ 96(DX), R14 + VMOVDQU Y4, (R14)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x5_loop + VZEROUPPER + +mulAvxTwo_9x5_end: + RET + +// func mulAvxTwo_9x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 119 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x6_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (BP)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (SI)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (DI)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R8)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R9)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 5 to 6 outputs + VMOVDQU (R10)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1920(CX), Y7 + VMOVDQU 1952(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1984(CX), Y7 + VMOVDQU 2016(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2048(CX), Y7 + VMOVDQU 2080(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2112(CX), Y7 + VMOVDQU 2144(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2176(CX), Y7 + VMOVDQU 2208(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2240(CX), Y7 + VMOVDQU 2272(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 6 to 6 outputs + VMOVDQU (R11)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2304(CX), Y7 + VMOVDQU 2336(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2368(CX), Y7 + VMOVDQU 2400(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2432(CX), Y7 + VMOVDQU 2464(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2496(CX), Y7 + VMOVDQU 2528(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2560(CX), Y7 + VMOVDQU 2592(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2624(CX), Y7 + VMOVDQU 2656(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 7 to 6 outputs + VMOVDQU (R12)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2688(CX), Y7 + VMOVDQU 2720(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2752(CX), Y7 + VMOVDQU 2784(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2816(CX), Y7 + VMOVDQU 2848(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2880(CX), Y7 + VMOVDQU 2912(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2944(CX), Y7 + VMOVDQU 2976(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3008(CX), Y7 + VMOVDQU 3040(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 8 to 6 outputs + VMOVDQU (BX)(R13*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 3072(CX), Y7 + VMOVDQU 3104(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 3136(CX), Y7 + VMOVDQU 3168(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 3200(CX), Y7 + VMOVDQU 3232(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 3264(CX), Y7 + VMOVDQU 3296(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 3328(CX), Y7 + VMOVDQU 3360(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3392(CX), Y7 + VMOVDQU 3424(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + MOVQ (DX), R14 + VMOVDQU Y0, (R14)(R13*1) + MOVQ 24(DX), R14 + VMOVDQU Y1, (R14)(R13*1) + MOVQ 48(DX), R14 + VMOVDQU Y2, (R14)(R13*1) + MOVQ 72(DX), R14 + VMOVDQU Y3, (R14)(R13*1) + MOVQ 96(DX), R14 + VMOVDQU Y4, (R14)(R13*1) + MOVQ 120(DX), R14 + VMOVDQU Y5, (R14)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x6_loop + VZEROUPPER + +mulAvxTwo_9x6_end: + RET + +// func mulAvxTwo_9x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 138 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x7_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (BP)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (SI)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (DI)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R8)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R9)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 5 to 7 outputs + VMOVDQU (R10)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2240(CX), Y8 + VMOVDQU 2272(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2304(CX), Y8 + VMOVDQU 2336(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2368(CX), Y8 + VMOVDQU 2400(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2432(CX), Y8 + VMOVDQU 2464(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2496(CX), Y8 + VMOVDQU 2528(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2560(CX), Y8 + VMOVDQU 2592(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2624(CX), Y8 + VMOVDQU 2656(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 6 to 7 outputs + VMOVDQU (R11)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2688(CX), Y8 + VMOVDQU 2720(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2752(CX), Y8 + VMOVDQU 2784(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2816(CX), Y8 + VMOVDQU 2848(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2880(CX), Y8 + VMOVDQU 2912(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2944(CX), Y8 + VMOVDQU 2976(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3008(CX), Y8 + VMOVDQU 3040(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3072(CX), Y8 + VMOVDQU 3104(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 7 to 7 outputs + VMOVDQU (R12)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 3136(CX), Y8 + VMOVDQU 3168(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 3200(CX), Y8 + VMOVDQU 3232(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 3264(CX), Y8 + VMOVDQU 3296(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 3328(CX), Y8 + VMOVDQU 3360(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 3392(CX), Y8 + VMOVDQU 3424(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3456(CX), Y8 + VMOVDQU 3488(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3520(CX), Y8 + VMOVDQU 3552(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 8 to 7 outputs + VMOVDQU (BX)(R13*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 3584(CX), Y8 + VMOVDQU 3616(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 3648(CX), Y8 + VMOVDQU 3680(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 3712(CX), Y8 + VMOVDQU 3744(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 3776(CX), Y8 + VMOVDQU 3808(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 3840(CX), Y8 + VMOVDQU 3872(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3904(CX), Y8 + VMOVDQU 3936(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3968(CX), Y8 + VMOVDQU 4000(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + MOVQ (DX), R14 + VMOVDQU Y0, (R14)(R13*1) + MOVQ 24(DX), R14 + VMOVDQU Y1, (R14)(R13*1) + MOVQ 48(DX), R14 + VMOVDQU Y2, (R14)(R13*1) + MOVQ 72(DX), R14 + VMOVDQU Y3, (R14)(R13*1) + MOVQ 96(DX), R14 + VMOVDQU Y4, (R14)(R13*1) + MOVQ 120(DX), R14 + VMOVDQU Y5, (R14)(R13*1) + MOVQ 144(DX), R14 + VMOVDQU Y6, (R14)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x7_loop + VZEROUPPER + +mulAvxTwo_9x7_end: + RET + +// func mulAvxTwo_9x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_9x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 157 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_9x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), BX + MOVQ $0x0000000f, R13 + MOVQ R13, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R13 + +mulAvxTwo_9x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (R9)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 5 to 8 outputs + VMOVDQU (R10)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2560(CX), Y9 + VMOVDQU 2592(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2624(CX), Y9 + VMOVDQU 2656(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2688(CX), Y9 + VMOVDQU 2720(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2752(CX), Y9 + VMOVDQU 2784(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2816(CX), Y9 + VMOVDQU 2848(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2880(CX), Y9 + VMOVDQU 2912(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2944(CX), Y9 + VMOVDQU 2976(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3008(CX), Y9 + VMOVDQU 3040(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 6 to 8 outputs + VMOVDQU (R11)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3072(CX), Y9 + VMOVDQU 3104(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3136(CX), Y9 + VMOVDQU 3168(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3200(CX), Y9 + VMOVDQU 3232(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3264(CX), Y9 + VMOVDQU 3296(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3328(CX), Y9 + VMOVDQU 3360(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3392(CX), Y9 + VMOVDQU 3424(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3456(CX), Y9 + VMOVDQU 3488(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3520(CX), Y9 + VMOVDQU 3552(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 7 to 8 outputs + VMOVDQU (R12)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3584(CX), Y9 + VMOVDQU 3616(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3648(CX), Y9 + VMOVDQU 3680(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3712(CX), Y9 + VMOVDQU 3744(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3776(CX), Y9 + VMOVDQU 3808(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3840(CX), Y9 + VMOVDQU 3872(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3904(CX), Y9 + VMOVDQU 3936(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3968(CX), Y9 + VMOVDQU 4000(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 4032(CX), Y9 + VMOVDQU 4064(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 8 to 8 outputs + VMOVDQU (BX)(R13*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 4096(CX), Y9 + VMOVDQU 4128(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 4160(CX), Y9 + VMOVDQU 4192(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 4224(CX), Y9 + VMOVDQU 4256(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 4288(CX), Y9 + VMOVDQU 4320(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 4352(CX), Y9 + VMOVDQU 4384(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 4416(CX), Y9 + VMOVDQU 4448(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 4480(CX), Y9 + VMOVDQU 4512(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 4544(CX), Y9 + VMOVDQU 4576(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R14 + VMOVDQU Y0, (R14)(R13*1) + MOVQ 24(DX), R14 + VMOVDQU Y1, (R14)(R13*1) + MOVQ 48(DX), R14 + VMOVDQU Y2, (R14)(R13*1) + MOVQ 72(DX), R14 + VMOVDQU Y3, (R14)(R13*1) + MOVQ 96(DX), R14 + VMOVDQU Y4, (R14)(R13*1) + MOVQ 120(DX), R14 + VMOVDQU Y5, (R14)(R13*1) + MOVQ 144(DX), R14 + VMOVDQU Y6, (R14)(R13*1) + MOVQ 168(DX), R14 + VMOVDQU Y7, (R14)(R13*1) + + // Prepare for next loop + ADDQ $0x20, R13 + DECQ AX + JNZ mulAvxTwo_9x8_loop + VZEROUPPER + +mulAvxTwo_9x8_end: + RET + +// func mulAvxTwo_10x1(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x1(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 24 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x1_end + MOVQ out_base+48(FP), DX + MOVQ (DX), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X1 + VPBROADCASTB X1, Y1 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x1_loop: + // Clear 1 outputs + VPXOR Y0, Y0, Y0 + + // Load and process 32 bytes from input 0 to 1 outputs + VMOVDQU (BP)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU (CX), Y2 + VMOVDQU 32(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 1 to 1 outputs + VMOVDQU (SI)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 64(CX), Y2 + VMOVDQU 96(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 2 to 1 outputs + VMOVDQU (DI)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 128(CX), Y2 + VMOVDQU 160(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 3 to 1 outputs + VMOVDQU (R8)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 192(CX), Y2 + VMOVDQU 224(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 4 to 1 outputs + VMOVDQU (R9)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 256(CX), Y2 + VMOVDQU 288(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 5 to 1 outputs + VMOVDQU (R10)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 320(CX), Y2 + VMOVDQU 352(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 6 to 1 outputs + VMOVDQU (R11)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 384(CX), Y2 + VMOVDQU 416(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 7 to 1 outputs + VMOVDQU (R12)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 448(CX), Y2 + VMOVDQU 480(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 8 to 1 outputs + VMOVDQU (R13)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 512(CX), Y2 + VMOVDQU 544(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Load and process 32 bytes from input 9 to 1 outputs + VMOVDQU (BX)(R14*1), Y4 + VPSRLQ $0x04, Y4, Y5 + VPAND Y1, Y4, Y4 + VPAND Y1, Y5, Y5 + VMOVDQU 576(CX), Y2 + VMOVDQU 608(CX), Y3 + VPSHUFB Y4, Y2, Y2 + VPSHUFB Y5, Y3, Y3 + VPXOR Y2, Y3, Y2 + VPXOR Y2, Y0, Y0 + + // Store 1 outputs + VMOVDQU Y0, (DX)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x1_loop + VZEROUPPER + +mulAvxTwo_10x1_end: + RET + +// func mulAvxTwo_10x2(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x2(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 47 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x2_end + MOVQ out_base+48(FP), DX + MOVQ (DX), BX + MOVQ 24(DX), DX + MOVQ in_base+24(FP), BP + MOVQ (BP), SI + MOVQ 24(BP), DI + MOVQ 48(BP), R8 + MOVQ 72(BP), R9 + MOVQ 96(BP), R10 + MOVQ 120(BP), R11 + MOVQ 144(BP), R12 + MOVQ 168(BP), R13 + MOVQ 192(BP), R14 + MOVQ 216(BP), BP + MOVQ $0x0000000f, R15 + MOVQ R15, X2 + VPBROADCASTB X2, Y2 + MOVQ start+72(FP), R15 + +mulAvxTwo_10x2_loop: + // Clear 2 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + + // Load and process 32 bytes from input 0 to 2 outputs + VMOVDQU (SI)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU (CX), Y3 + VMOVDQU 32(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 64(CX), Y3 + VMOVDQU 96(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 1 to 2 outputs + VMOVDQU (DI)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 128(CX), Y3 + VMOVDQU 160(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 192(CX), Y3 + VMOVDQU 224(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 2 to 2 outputs + VMOVDQU (R8)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 256(CX), Y3 + VMOVDQU 288(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 320(CX), Y3 + VMOVDQU 352(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 3 to 2 outputs + VMOVDQU (R9)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 384(CX), Y3 + VMOVDQU 416(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 448(CX), Y3 + VMOVDQU 480(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 4 to 2 outputs + VMOVDQU (R10)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 512(CX), Y3 + VMOVDQU 544(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 576(CX), Y3 + VMOVDQU 608(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 5 to 2 outputs + VMOVDQU (R11)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 640(CX), Y3 + VMOVDQU 672(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 704(CX), Y3 + VMOVDQU 736(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 6 to 2 outputs + VMOVDQU (R12)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 768(CX), Y3 + VMOVDQU 800(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 832(CX), Y3 + VMOVDQU 864(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 7 to 2 outputs + VMOVDQU (R13)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 896(CX), Y3 + VMOVDQU 928(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 960(CX), Y3 + VMOVDQU 992(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 8 to 2 outputs + VMOVDQU (R14)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 1024(CX), Y3 + VMOVDQU 1056(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 1088(CX), Y3 + VMOVDQU 1120(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Load and process 32 bytes from input 9 to 2 outputs + VMOVDQU (BP)(R15*1), Y5 + VPSRLQ $0x04, Y5, Y6 + VPAND Y2, Y5, Y5 + VPAND Y2, Y6, Y6 + VMOVDQU 1152(CX), Y3 + VMOVDQU 1184(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y0, Y0 + VMOVDQU 1216(CX), Y3 + VMOVDQU 1248(CX), Y4 + VPSHUFB Y5, Y3, Y3 + VPSHUFB Y6, Y4, Y4 + VPXOR Y3, Y4, Y3 + VPXOR Y3, Y1, Y1 + + // Store 2 outputs + VMOVDQU Y0, (BX)(R15*1) + VMOVDQU Y1, (DX)(R15*1) + + // Prepare for next loop + ADDQ $0x20, R15 + DECQ AX + JNZ mulAvxTwo_10x2_loop + VZEROUPPER + +mulAvxTwo_10x2_end: + RET + +// func mulAvxTwo_10x3(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x3(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 68 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x3_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X3 + VPBROADCASTB X3, Y3 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x3_loop: + // Clear 3 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + + // Load and process 32 bytes from input 0 to 3 outputs + VMOVDQU (BP)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU (CX), Y4 + VMOVDQU 32(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 64(CX), Y4 + VMOVDQU 96(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 128(CX), Y4 + VMOVDQU 160(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 1 to 3 outputs + VMOVDQU (SI)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 192(CX), Y4 + VMOVDQU 224(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 256(CX), Y4 + VMOVDQU 288(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 320(CX), Y4 + VMOVDQU 352(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 2 to 3 outputs + VMOVDQU (DI)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 384(CX), Y4 + VMOVDQU 416(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 448(CX), Y4 + VMOVDQU 480(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 512(CX), Y4 + VMOVDQU 544(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 3 to 3 outputs + VMOVDQU (R8)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 576(CX), Y4 + VMOVDQU 608(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 640(CX), Y4 + VMOVDQU 672(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 704(CX), Y4 + VMOVDQU 736(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 4 to 3 outputs + VMOVDQU (R9)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 768(CX), Y4 + VMOVDQU 800(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 832(CX), Y4 + VMOVDQU 864(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 896(CX), Y4 + VMOVDQU 928(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 5 to 3 outputs + VMOVDQU (R10)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 960(CX), Y4 + VMOVDQU 992(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1024(CX), Y4 + VMOVDQU 1056(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1088(CX), Y4 + VMOVDQU 1120(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 6 to 3 outputs + VMOVDQU (R11)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1152(CX), Y4 + VMOVDQU 1184(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1216(CX), Y4 + VMOVDQU 1248(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1280(CX), Y4 + VMOVDQU 1312(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 7 to 3 outputs + VMOVDQU (R12)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1344(CX), Y4 + VMOVDQU 1376(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1408(CX), Y4 + VMOVDQU 1440(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1472(CX), Y4 + VMOVDQU 1504(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 8 to 3 outputs + VMOVDQU (R13)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1536(CX), Y4 + VMOVDQU 1568(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1600(CX), Y4 + VMOVDQU 1632(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1664(CX), Y4 + VMOVDQU 1696(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Load and process 32 bytes from input 9 to 3 outputs + VMOVDQU (BX)(R14*1), Y6 + VPSRLQ $0x04, Y6, Y7 + VPAND Y3, Y6, Y6 + VPAND Y3, Y7, Y7 + VMOVDQU 1728(CX), Y4 + VMOVDQU 1760(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y0, Y0 + VMOVDQU 1792(CX), Y4 + VMOVDQU 1824(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y1, Y1 + VMOVDQU 1856(CX), Y4 + VMOVDQU 1888(CX), Y5 + VPSHUFB Y6, Y4, Y4 + VPSHUFB Y7, Y5, Y5 + VPXOR Y4, Y5, Y4 + VPXOR Y4, Y2, Y2 + + // Store 3 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x3_loop + VZEROUPPER + +mulAvxTwo_10x3_end: + RET + +// func mulAvxTwo_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x4(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 89 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x4_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X4 + VPBROADCASTB X4, Y4 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x4_loop: + // Clear 4 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + + // Load and process 32 bytes from input 0 to 4 outputs + VMOVDQU (BP)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU (CX), Y5 + VMOVDQU 32(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 64(CX), Y5 + VMOVDQU 96(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 128(CX), Y5 + VMOVDQU 160(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 192(CX), Y5 + VMOVDQU 224(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 1 to 4 outputs + VMOVDQU (SI)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 256(CX), Y5 + VMOVDQU 288(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 320(CX), Y5 + VMOVDQU 352(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 384(CX), Y5 + VMOVDQU 416(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 448(CX), Y5 + VMOVDQU 480(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 2 to 4 outputs + VMOVDQU (DI)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 512(CX), Y5 + VMOVDQU 544(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 576(CX), Y5 + VMOVDQU 608(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 640(CX), Y5 + VMOVDQU 672(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 704(CX), Y5 + VMOVDQU 736(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 3 to 4 outputs + VMOVDQU (R8)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 768(CX), Y5 + VMOVDQU 800(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 832(CX), Y5 + VMOVDQU 864(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 896(CX), Y5 + VMOVDQU 928(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 960(CX), Y5 + VMOVDQU 992(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 4 to 4 outputs + VMOVDQU (R9)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1024(CX), Y5 + VMOVDQU 1056(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1088(CX), Y5 + VMOVDQU 1120(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1152(CX), Y5 + VMOVDQU 1184(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1216(CX), Y5 + VMOVDQU 1248(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 5 to 4 outputs + VMOVDQU (R10)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1280(CX), Y5 + VMOVDQU 1312(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1344(CX), Y5 + VMOVDQU 1376(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1408(CX), Y5 + VMOVDQU 1440(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1472(CX), Y5 + VMOVDQU 1504(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 6 to 4 outputs + VMOVDQU (R11)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1536(CX), Y5 + VMOVDQU 1568(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1600(CX), Y5 + VMOVDQU 1632(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1664(CX), Y5 + VMOVDQU 1696(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1728(CX), Y5 + VMOVDQU 1760(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 7 to 4 outputs + VMOVDQU (R12)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 1792(CX), Y5 + VMOVDQU 1824(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 1856(CX), Y5 + VMOVDQU 1888(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 1920(CX), Y5 + VMOVDQU 1952(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 1984(CX), Y5 + VMOVDQU 2016(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 8 to 4 outputs + VMOVDQU (R13)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 2048(CX), Y5 + VMOVDQU 2080(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 2112(CX), Y5 + VMOVDQU 2144(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 2176(CX), Y5 + VMOVDQU 2208(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 2240(CX), Y5 + VMOVDQU 2272(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Load and process 32 bytes from input 9 to 4 outputs + VMOVDQU (BX)(R14*1), Y7 + VPSRLQ $0x04, Y7, Y8 + VPAND Y4, Y7, Y7 + VPAND Y4, Y8, Y8 + VMOVDQU 2304(CX), Y5 + VMOVDQU 2336(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y0, Y0 + VMOVDQU 2368(CX), Y5 + VMOVDQU 2400(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y1, Y1 + VMOVDQU 2432(CX), Y5 + VMOVDQU 2464(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y2, Y2 + VMOVDQU 2496(CX), Y5 + VMOVDQU 2528(CX), Y6 + VPSHUFB Y7, Y5, Y5 + VPSHUFB Y8, Y6, Y6 + VPXOR Y5, Y6, Y5 + VPXOR Y5, Y3, Y3 + + // Store 4 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + MOVQ 72(DX), R15 + VMOVDQU Y3, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x4_loop + VZEROUPPER + +mulAvxTwo_10x4_end: + RET + +// func mulAvxTwo_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x5(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 110 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x5_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X5 + VPBROADCASTB X5, Y5 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x5_loop: + // Clear 5 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + + // Load and process 32 bytes from input 0 to 5 outputs + VMOVDQU (BP)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU (CX), Y6 + VMOVDQU 32(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 64(CX), Y6 + VMOVDQU 96(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 128(CX), Y6 + VMOVDQU 160(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 192(CX), Y6 + VMOVDQU 224(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 256(CX), Y6 + VMOVDQU 288(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 1 to 5 outputs + VMOVDQU (SI)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 320(CX), Y6 + VMOVDQU 352(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 384(CX), Y6 + VMOVDQU 416(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 448(CX), Y6 + VMOVDQU 480(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 512(CX), Y6 + VMOVDQU 544(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 576(CX), Y6 + VMOVDQU 608(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 2 to 5 outputs + VMOVDQU (DI)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 640(CX), Y6 + VMOVDQU 672(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 704(CX), Y6 + VMOVDQU 736(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 768(CX), Y6 + VMOVDQU 800(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 832(CX), Y6 + VMOVDQU 864(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 896(CX), Y6 + VMOVDQU 928(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 3 to 5 outputs + VMOVDQU (R8)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 960(CX), Y6 + VMOVDQU 992(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1024(CX), Y6 + VMOVDQU 1056(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1088(CX), Y6 + VMOVDQU 1120(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1152(CX), Y6 + VMOVDQU 1184(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1216(CX), Y6 + VMOVDQU 1248(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 4 to 5 outputs + VMOVDQU (R9)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1280(CX), Y6 + VMOVDQU 1312(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1344(CX), Y6 + VMOVDQU 1376(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1408(CX), Y6 + VMOVDQU 1440(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1472(CX), Y6 + VMOVDQU 1504(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1536(CX), Y6 + VMOVDQU 1568(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 5 to 5 outputs + VMOVDQU (R10)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1600(CX), Y6 + VMOVDQU 1632(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1664(CX), Y6 + VMOVDQU 1696(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 1728(CX), Y6 + VMOVDQU 1760(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 1792(CX), Y6 + VMOVDQU 1824(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 1856(CX), Y6 + VMOVDQU 1888(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 6 to 5 outputs + VMOVDQU (R11)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 1920(CX), Y6 + VMOVDQU 1952(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 1984(CX), Y6 + VMOVDQU 2016(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2048(CX), Y6 + VMOVDQU 2080(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2112(CX), Y6 + VMOVDQU 2144(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2176(CX), Y6 + VMOVDQU 2208(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 7 to 5 outputs + VMOVDQU (R12)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2240(CX), Y6 + VMOVDQU 2272(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2304(CX), Y6 + VMOVDQU 2336(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2368(CX), Y6 + VMOVDQU 2400(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2432(CX), Y6 + VMOVDQU 2464(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2496(CX), Y6 + VMOVDQU 2528(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 8 to 5 outputs + VMOVDQU (R13)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2560(CX), Y6 + VMOVDQU 2592(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2624(CX), Y6 + VMOVDQU 2656(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 2688(CX), Y6 + VMOVDQU 2720(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 2752(CX), Y6 + VMOVDQU 2784(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 2816(CX), Y6 + VMOVDQU 2848(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Load and process 32 bytes from input 9 to 5 outputs + VMOVDQU (BX)(R14*1), Y8 + VPSRLQ $0x04, Y8, Y9 + VPAND Y5, Y8, Y8 + VPAND Y5, Y9, Y9 + VMOVDQU 2880(CX), Y6 + VMOVDQU 2912(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y0, Y0 + VMOVDQU 2944(CX), Y6 + VMOVDQU 2976(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y1, Y1 + VMOVDQU 3008(CX), Y6 + VMOVDQU 3040(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y2, Y2 + VMOVDQU 3072(CX), Y6 + VMOVDQU 3104(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y3, Y3 + VMOVDQU 3136(CX), Y6 + VMOVDQU 3168(CX), Y7 + VPSHUFB Y8, Y6, Y6 + VPSHUFB Y9, Y7, Y7 + VPXOR Y6, Y7, Y6 + VPXOR Y6, Y4, Y4 + + // Store 5 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + MOVQ 72(DX), R15 + VMOVDQU Y3, (R15)(R14*1) + MOVQ 96(DX), R15 + VMOVDQU Y4, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x5_loop + VZEROUPPER + +mulAvxTwo_10x5_end: + RET + +// func mulAvxTwo_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x6(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 131 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x6_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X6 + VPBROADCASTB X6, Y6 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x6_loop: + // Clear 6 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + + // Load and process 32 bytes from input 0 to 6 outputs + VMOVDQU (BP)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU (CX), Y7 + VMOVDQU 32(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 64(CX), Y7 + VMOVDQU 96(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 128(CX), Y7 + VMOVDQU 160(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 192(CX), Y7 + VMOVDQU 224(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 256(CX), Y7 + VMOVDQU 288(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 320(CX), Y7 + VMOVDQU 352(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 1 to 6 outputs + VMOVDQU (SI)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 384(CX), Y7 + VMOVDQU 416(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 448(CX), Y7 + VMOVDQU 480(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 512(CX), Y7 + VMOVDQU 544(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 576(CX), Y7 + VMOVDQU 608(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 640(CX), Y7 + VMOVDQU 672(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 704(CX), Y7 + VMOVDQU 736(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 2 to 6 outputs + VMOVDQU (DI)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 768(CX), Y7 + VMOVDQU 800(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 832(CX), Y7 + VMOVDQU 864(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 896(CX), Y7 + VMOVDQU 928(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 960(CX), Y7 + VMOVDQU 992(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1024(CX), Y7 + VMOVDQU 1056(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1088(CX), Y7 + VMOVDQU 1120(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 3 to 6 outputs + VMOVDQU (R8)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1152(CX), Y7 + VMOVDQU 1184(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1216(CX), Y7 + VMOVDQU 1248(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1280(CX), Y7 + VMOVDQU 1312(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1344(CX), Y7 + VMOVDQU 1376(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1408(CX), Y7 + VMOVDQU 1440(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1472(CX), Y7 + VMOVDQU 1504(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 4 to 6 outputs + VMOVDQU (R9)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1536(CX), Y7 + VMOVDQU 1568(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1600(CX), Y7 + VMOVDQU 1632(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 1664(CX), Y7 + VMOVDQU 1696(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 1728(CX), Y7 + VMOVDQU 1760(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 1792(CX), Y7 + VMOVDQU 1824(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 1856(CX), Y7 + VMOVDQU 1888(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 5 to 6 outputs + VMOVDQU (R10)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 1920(CX), Y7 + VMOVDQU 1952(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 1984(CX), Y7 + VMOVDQU 2016(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2048(CX), Y7 + VMOVDQU 2080(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2112(CX), Y7 + VMOVDQU 2144(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2176(CX), Y7 + VMOVDQU 2208(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2240(CX), Y7 + VMOVDQU 2272(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 6 to 6 outputs + VMOVDQU (R11)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2304(CX), Y7 + VMOVDQU 2336(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2368(CX), Y7 + VMOVDQU 2400(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2432(CX), Y7 + VMOVDQU 2464(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2496(CX), Y7 + VMOVDQU 2528(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2560(CX), Y7 + VMOVDQU 2592(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 2624(CX), Y7 + VMOVDQU 2656(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 7 to 6 outputs + VMOVDQU (R12)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 2688(CX), Y7 + VMOVDQU 2720(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 2752(CX), Y7 + VMOVDQU 2784(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 2816(CX), Y7 + VMOVDQU 2848(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 2880(CX), Y7 + VMOVDQU 2912(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 2944(CX), Y7 + VMOVDQU 2976(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3008(CX), Y7 + VMOVDQU 3040(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 8 to 6 outputs + VMOVDQU (R13)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 3072(CX), Y7 + VMOVDQU 3104(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 3136(CX), Y7 + VMOVDQU 3168(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 3200(CX), Y7 + VMOVDQU 3232(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 3264(CX), Y7 + VMOVDQU 3296(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 3328(CX), Y7 + VMOVDQU 3360(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3392(CX), Y7 + VMOVDQU 3424(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Load and process 32 bytes from input 9 to 6 outputs + VMOVDQU (BX)(R14*1), Y9 + VPSRLQ $0x04, Y9, Y10 + VPAND Y6, Y9, Y9 + VPAND Y6, Y10, Y10 + VMOVDQU 3456(CX), Y7 + VMOVDQU 3488(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y0, Y0 + VMOVDQU 3520(CX), Y7 + VMOVDQU 3552(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y1, Y1 + VMOVDQU 3584(CX), Y7 + VMOVDQU 3616(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y2, Y2 + VMOVDQU 3648(CX), Y7 + VMOVDQU 3680(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y3, Y3 + VMOVDQU 3712(CX), Y7 + VMOVDQU 3744(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y4, Y4 + VMOVDQU 3776(CX), Y7 + VMOVDQU 3808(CX), Y8 + VPSHUFB Y9, Y7, Y7 + VPSHUFB Y10, Y8, Y8 + VPXOR Y7, Y8, Y7 + VPXOR Y7, Y5, Y5 + + // Store 6 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + MOVQ 72(DX), R15 + VMOVDQU Y3, (R15)(R14*1) + MOVQ 96(DX), R15 + VMOVDQU Y4, (R15)(R14*1) + MOVQ 120(DX), R15 + VMOVDQU Y5, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x6_loop + VZEROUPPER + +mulAvxTwo_10x6_end: + RET + +// func mulAvxTwo_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x7(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 152 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x7_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X7 + VPBROADCASTB X7, Y7 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x7_loop: + // Clear 7 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + + // Load and process 32 bytes from input 0 to 7 outputs + VMOVDQU (BP)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU (CX), Y8 + VMOVDQU 32(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 64(CX), Y8 + VMOVDQU 96(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 128(CX), Y8 + VMOVDQU 160(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 192(CX), Y8 + VMOVDQU 224(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 256(CX), Y8 + VMOVDQU 288(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 320(CX), Y8 + VMOVDQU 352(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 384(CX), Y8 + VMOVDQU 416(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 1 to 7 outputs + VMOVDQU (SI)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 448(CX), Y8 + VMOVDQU 480(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 512(CX), Y8 + VMOVDQU 544(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 576(CX), Y8 + VMOVDQU 608(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 640(CX), Y8 + VMOVDQU 672(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 704(CX), Y8 + VMOVDQU 736(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 768(CX), Y8 + VMOVDQU 800(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 832(CX), Y8 + VMOVDQU 864(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 2 to 7 outputs + VMOVDQU (DI)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 896(CX), Y8 + VMOVDQU 928(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 960(CX), Y8 + VMOVDQU 992(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1024(CX), Y8 + VMOVDQU 1056(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1088(CX), Y8 + VMOVDQU 1120(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1152(CX), Y8 + VMOVDQU 1184(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1216(CX), Y8 + VMOVDQU 1248(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1280(CX), Y8 + VMOVDQU 1312(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 3 to 7 outputs + VMOVDQU (R8)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1344(CX), Y8 + VMOVDQU 1376(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1408(CX), Y8 + VMOVDQU 1440(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1472(CX), Y8 + VMOVDQU 1504(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1536(CX), Y8 + VMOVDQU 1568(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 1600(CX), Y8 + VMOVDQU 1632(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 1664(CX), Y8 + VMOVDQU 1696(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 1728(CX), Y8 + VMOVDQU 1760(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 4 to 7 outputs + VMOVDQU (R9)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 1792(CX), Y8 + VMOVDQU 1824(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 1856(CX), Y8 + VMOVDQU 1888(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 1920(CX), Y8 + VMOVDQU 1952(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 1984(CX), Y8 + VMOVDQU 2016(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2048(CX), Y8 + VMOVDQU 2080(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2112(CX), Y8 + VMOVDQU 2144(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2176(CX), Y8 + VMOVDQU 2208(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 5 to 7 outputs + VMOVDQU (R10)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2240(CX), Y8 + VMOVDQU 2272(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2304(CX), Y8 + VMOVDQU 2336(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2368(CX), Y8 + VMOVDQU 2400(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2432(CX), Y8 + VMOVDQU 2464(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2496(CX), Y8 + VMOVDQU 2528(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 2560(CX), Y8 + VMOVDQU 2592(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 2624(CX), Y8 + VMOVDQU 2656(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 6 to 7 outputs + VMOVDQU (R11)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 2688(CX), Y8 + VMOVDQU 2720(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 2752(CX), Y8 + VMOVDQU 2784(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 2816(CX), Y8 + VMOVDQU 2848(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 2880(CX), Y8 + VMOVDQU 2912(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 2944(CX), Y8 + VMOVDQU 2976(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3008(CX), Y8 + VMOVDQU 3040(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3072(CX), Y8 + VMOVDQU 3104(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 7 to 7 outputs + VMOVDQU (R12)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 3136(CX), Y8 + VMOVDQU 3168(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 3200(CX), Y8 + VMOVDQU 3232(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 3264(CX), Y8 + VMOVDQU 3296(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 3328(CX), Y8 + VMOVDQU 3360(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 3392(CX), Y8 + VMOVDQU 3424(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3456(CX), Y8 + VMOVDQU 3488(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3520(CX), Y8 + VMOVDQU 3552(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 8 to 7 outputs + VMOVDQU (R13)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 3584(CX), Y8 + VMOVDQU 3616(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 3648(CX), Y8 + VMOVDQU 3680(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 3712(CX), Y8 + VMOVDQU 3744(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 3776(CX), Y8 + VMOVDQU 3808(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 3840(CX), Y8 + VMOVDQU 3872(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 3904(CX), Y8 + VMOVDQU 3936(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 3968(CX), Y8 + VMOVDQU 4000(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Load and process 32 bytes from input 9 to 7 outputs + VMOVDQU (BX)(R14*1), Y10 + VPSRLQ $0x04, Y10, Y11 + VPAND Y7, Y10, Y10 + VPAND Y7, Y11, Y11 + VMOVDQU 4032(CX), Y8 + VMOVDQU 4064(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y0, Y0 + VMOVDQU 4096(CX), Y8 + VMOVDQU 4128(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y1, Y1 + VMOVDQU 4160(CX), Y8 + VMOVDQU 4192(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y2, Y2 + VMOVDQU 4224(CX), Y8 + VMOVDQU 4256(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y3, Y3 + VMOVDQU 4288(CX), Y8 + VMOVDQU 4320(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y4, Y4 + VMOVDQU 4352(CX), Y8 + VMOVDQU 4384(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y5, Y5 + VMOVDQU 4416(CX), Y8 + VMOVDQU 4448(CX), Y9 + VPSHUFB Y10, Y8, Y8 + VPSHUFB Y11, Y9, Y9 + VPXOR Y8, Y9, Y8 + VPXOR Y8, Y6, Y6 + + // Store 7 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + MOVQ 72(DX), R15 + VMOVDQU Y3, (R15)(R14*1) + MOVQ 96(DX), R15 + VMOVDQU Y4, (R15)(R14*1) + MOVQ 120(DX), R15 + VMOVDQU Y5, (R15)(R14*1) + MOVQ 144(DX), R15 + VMOVDQU Y6, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x7_loop + VZEROUPPER + +mulAvxTwo_10x7_end: + RET + +// func mulAvxTwo_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int) +// Requires: AVX, AVX2, SSE2 +TEXT ·mulAvxTwo_10x8(SB), $0-88 + // Loading no tables to registers + // Full registers estimated 173 YMM used + MOVQ n+80(FP), AX + MOVQ matrix_base+0(FP), CX + SHRQ $0x05, AX + TESTQ AX, AX + JZ mulAvxTwo_10x8_end + MOVQ out_base+48(FP), DX + MOVQ in_base+24(FP), BX + MOVQ (BX), BP + MOVQ 24(BX), SI + MOVQ 48(BX), DI + MOVQ 72(BX), R8 + MOVQ 96(BX), R9 + MOVQ 120(BX), R10 + MOVQ 144(BX), R11 + MOVQ 168(BX), R12 + MOVQ 192(BX), R13 + MOVQ 216(BX), BX + MOVQ $0x0000000f, R14 + MOVQ R14, X8 + VPBROADCASTB X8, Y8 + MOVQ start+72(FP), R14 + +mulAvxTwo_10x8_loop: + // Clear 8 outputs + VPXOR Y0, Y0, Y0 + VPXOR Y1, Y1, Y1 + VPXOR Y2, Y2, Y2 + VPXOR Y3, Y3, Y3 + VPXOR Y4, Y4, Y4 + VPXOR Y5, Y5, Y5 + VPXOR Y6, Y6, Y6 + VPXOR Y7, Y7, Y7 + + // Load and process 32 bytes from input 0 to 8 outputs + VMOVDQU (BP)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU (CX), Y9 + VMOVDQU 32(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 64(CX), Y9 + VMOVDQU 96(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 128(CX), Y9 + VMOVDQU 160(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 192(CX), Y9 + VMOVDQU 224(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 256(CX), Y9 + VMOVDQU 288(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 320(CX), Y9 + VMOVDQU 352(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 384(CX), Y9 + VMOVDQU 416(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 448(CX), Y9 + VMOVDQU 480(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 1 to 8 outputs + VMOVDQU (SI)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 512(CX), Y9 + VMOVDQU 544(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 576(CX), Y9 + VMOVDQU 608(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 640(CX), Y9 + VMOVDQU 672(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 704(CX), Y9 + VMOVDQU 736(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 768(CX), Y9 + VMOVDQU 800(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 832(CX), Y9 + VMOVDQU 864(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 896(CX), Y9 + VMOVDQU 928(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 960(CX), Y9 + VMOVDQU 992(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 2 to 8 outputs + VMOVDQU (DI)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1024(CX), Y9 + VMOVDQU 1056(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1088(CX), Y9 + VMOVDQU 1120(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1152(CX), Y9 + VMOVDQU 1184(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1216(CX), Y9 + VMOVDQU 1248(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1280(CX), Y9 + VMOVDQU 1312(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1344(CX), Y9 + VMOVDQU 1376(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1408(CX), Y9 + VMOVDQU 1440(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1472(CX), Y9 + VMOVDQU 1504(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 3 to 8 outputs + VMOVDQU (R8)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 1536(CX), Y9 + VMOVDQU 1568(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 1600(CX), Y9 + VMOVDQU 1632(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 1664(CX), Y9 + VMOVDQU 1696(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 1728(CX), Y9 + VMOVDQU 1760(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 1792(CX), Y9 + VMOVDQU 1824(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 1856(CX), Y9 + VMOVDQU 1888(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 1920(CX), Y9 + VMOVDQU 1952(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 1984(CX), Y9 + VMOVDQU 2016(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 4 to 8 outputs + VMOVDQU (R9)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2048(CX), Y9 + VMOVDQU 2080(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2112(CX), Y9 + VMOVDQU 2144(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2176(CX), Y9 + VMOVDQU 2208(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2240(CX), Y9 + VMOVDQU 2272(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2304(CX), Y9 + VMOVDQU 2336(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2368(CX), Y9 + VMOVDQU 2400(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2432(CX), Y9 + VMOVDQU 2464(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 2496(CX), Y9 + VMOVDQU 2528(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 5 to 8 outputs + VMOVDQU (R10)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 2560(CX), Y9 + VMOVDQU 2592(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 2624(CX), Y9 + VMOVDQU 2656(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 2688(CX), Y9 + VMOVDQU 2720(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 2752(CX), Y9 + VMOVDQU 2784(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 2816(CX), Y9 + VMOVDQU 2848(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 2880(CX), Y9 + VMOVDQU 2912(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 2944(CX), Y9 + VMOVDQU 2976(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3008(CX), Y9 + VMOVDQU 3040(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 6 to 8 outputs + VMOVDQU (R11)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3072(CX), Y9 + VMOVDQU 3104(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3136(CX), Y9 + VMOVDQU 3168(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3200(CX), Y9 + VMOVDQU 3232(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3264(CX), Y9 + VMOVDQU 3296(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3328(CX), Y9 + VMOVDQU 3360(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3392(CX), Y9 + VMOVDQU 3424(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3456(CX), Y9 + VMOVDQU 3488(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 3520(CX), Y9 + VMOVDQU 3552(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 7 to 8 outputs + VMOVDQU (R12)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 3584(CX), Y9 + VMOVDQU 3616(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 3648(CX), Y9 + VMOVDQU 3680(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 3712(CX), Y9 + VMOVDQU 3744(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 3776(CX), Y9 + VMOVDQU 3808(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 3840(CX), Y9 + VMOVDQU 3872(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 3904(CX), Y9 + VMOVDQU 3936(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 3968(CX), Y9 + VMOVDQU 4000(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 4032(CX), Y9 + VMOVDQU 4064(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 8 to 8 outputs + VMOVDQU (R13)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 4096(CX), Y9 + VMOVDQU 4128(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 4160(CX), Y9 + VMOVDQU 4192(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 4224(CX), Y9 + VMOVDQU 4256(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 4288(CX), Y9 + VMOVDQU 4320(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 4352(CX), Y9 + VMOVDQU 4384(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 4416(CX), Y9 + VMOVDQU 4448(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 4480(CX), Y9 + VMOVDQU 4512(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 4544(CX), Y9 + VMOVDQU 4576(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Load and process 32 bytes from input 9 to 8 outputs + VMOVDQU (BX)(R14*1), Y11 + VPSRLQ $0x04, Y11, Y12 + VPAND Y8, Y11, Y11 + VPAND Y8, Y12, Y12 + VMOVDQU 4608(CX), Y9 + VMOVDQU 4640(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y0, Y0 + VMOVDQU 4672(CX), Y9 + VMOVDQU 4704(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y1, Y1 + VMOVDQU 4736(CX), Y9 + VMOVDQU 4768(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y2, Y2 + VMOVDQU 4800(CX), Y9 + VMOVDQU 4832(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y3, Y3 + VMOVDQU 4864(CX), Y9 + VMOVDQU 4896(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y4, Y4 + VMOVDQU 4928(CX), Y9 + VMOVDQU 4960(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y5, Y5 + VMOVDQU 4992(CX), Y9 + VMOVDQU 5024(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y6, Y6 + VMOVDQU 5056(CX), Y9 + VMOVDQU 5088(CX), Y10 + VPSHUFB Y11, Y9, Y9 + VPSHUFB Y12, Y10, Y10 + VPXOR Y9, Y10, Y9 + VPXOR Y9, Y7, Y7 + + // Store 8 outputs + MOVQ (DX), R15 + VMOVDQU Y0, (R15)(R14*1) + MOVQ 24(DX), R15 + VMOVDQU Y1, (R15)(R14*1) + MOVQ 48(DX), R15 + VMOVDQU Y2, (R15)(R14*1) + MOVQ 72(DX), R15 + VMOVDQU Y3, (R15)(R14*1) + MOVQ 96(DX), R15 + VMOVDQU Y4, (R15)(R14*1) + MOVQ 120(DX), R15 + VMOVDQU Y5, (R15)(R14*1) + MOVQ 144(DX), R15 + VMOVDQU Y6, (R15)(R14*1) + MOVQ 168(DX), R15 + VMOVDQU Y7, (R15)(R14*1) + + // Prepare for next loop + ADDQ $0x20, R14 + DECQ AX + JNZ mulAvxTwo_10x8_loop + VZEROUPPER + +mulAvxTwo_10x8_end: + RET diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go new file mode 100644 index 0000000..b4917bc --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go @@ -0,0 +1,11 @@ +//+build !amd64 noasm appengine gccgo nogen + +package reedsolomon + +const maxAvx2Inputs = 0 +const maxAvx2Outputs = 0 +const avx2CodeGen = false + +func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int { + panic("avx2 codegen not available") +} diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go new file mode 100644 index 0000000..0b49a1e --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go @@ -0,0 +1,293 @@ +// Code generated by command: go generate gen.go. DO NOT EDIT. + +// +build !appengine +// +build !noasm +// +build gc +// +build !nogen + +package reedsolomon + +import "fmt" + +const avx2CodeGen = true +const maxAvx2Inputs = 10 +const maxAvx2Outputs = 8 + +func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int { + n := stop - start + n = (n >> 5) << 5 + + switch len(in) { + case 1: + switch len(out) { + case 1: + mulAvxTwo_1x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_1x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_1x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_1x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_1x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_1x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_1x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_1x8(matrix, in, out, start, n) + return n + } + case 2: + switch len(out) { + case 1: + mulAvxTwo_2x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_2x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_2x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_2x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_2x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_2x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_2x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_2x8(matrix, in, out, start, n) + return n + } + case 3: + switch len(out) { + case 1: + mulAvxTwo_3x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_3x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_3x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_3x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_3x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_3x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_3x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_3x8(matrix, in, out, start, n) + return n + } + case 4: + switch len(out) { + case 1: + mulAvxTwo_4x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_4x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_4x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_4x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_4x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_4x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_4x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_4x8(matrix, in, out, start, n) + return n + } + case 5: + switch len(out) { + case 1: + mulAvxTwo_5x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_5x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_5x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_5x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_5x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_5x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_5x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_5x8(matrix, in, out, start, n) + return n + } + case 6: + switch len(out) { + case 1: + mulAvxTwo_6x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_6x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_6x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_6x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_6x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_6x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_6x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_6x8(matrix, in, out, start, n) + return n + } + case 7: + switch len(out) { + case 1: + mulAvxTwo_7x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_7x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_7x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_7x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_7x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_7x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_7x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_7x8(matrix, in, out, start, n) + return n + } + case 8: + switch len(out) { + case 1: + mulAvxTwo_8x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_8x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_8x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_8x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_8x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_8x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_8x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_8x8(matrix, in, out, start, n) + return n + } + case 9: + switch len(out) { + case 1: + mulAvxTwo_9x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_9x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_9x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_9x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_9x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_9x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_9x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_9x8(matrix, in, out, start, n) + return n + } + case 10: + switch len(out) { + case 1: + mulAvxTwo_10x1(matrix, in, out, start, n) + return n + case 2: + mulAvxTwo_10x2(matrix, in, out, start, n) + return n + case 3: + mulAvxTwo_10x3(matrix, in, out, start, n) + return n + case 4: + mulAvxTwo_10x4(matrix, in, out, start, n) + return n + case 5: + mulAvxTwo_10x5(matrix, in, out, start, n) + return n + case 6: + mulAvxTwo_10x6(matrix, in, out, start, n) + return n + case 7: + mulAvxTwo_10x7(matrix, in, out, start, n) + return n + case 8: + mulAvxTwo_10x8(matrix, in, out, start, n) + return n + } + } + panic(fmt.Sprintf("unhandled size: %dx%d", len(in), len(out))) +} diff --git a/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go b/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go new file mode 100644 index 0000000..bd15e3a --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go @@ -0,0 +1,13 @@ +//+build !amd64 noasm appengine gccgo + +// Copyright 2020, Klaus Post, see LICENSE for details. + +package reedsolomon + +func (r *reedSolomon) codeSomeShardsAvx512(matrixRows, inputs, outputs [][]byte, outputCount, byteCount int) { + panic("codeSomeShardsAvx512 should not be called if built without asm") +} + +func (r *reedSolomon) codeSomeShardsAvx512P(matrixRows, inputs, outputs [][]byte, outputCount, byteCount int) { + panic("codeSomeShardsAvx512P should not be called if built without asm") +} diff --git a/vendor/github.com/klauspost/reedsolomon/gen.go b/vendor/github.com/klauspost/reedsolomon/gen.go new file mode 100644 index 0000000..6fc545c --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/gen.go @@ -0,0 +1,249 @@ +//+build generate + +//go:generate go run gen.go -out galois_gen_amd64.s -stubs galois_gen_amd64.go +//go:generate gofmt -w galois_gen_switch_amd64.go + +package main + +import ( + "bufio" + "fmt" + "os" + + . "github.com/mmcloughlin/avo/build" + "github.com/mmcloughlin/avo/buildtags" + . "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// Technically we can do slightly bigger, but we stay reasonable. +const inputMax = 10 +const outputMax = 8 + +var switchDefs [inputMax][outputMax]string +var switchDefsX [inputMax][outputMax]string + +const perLoopBits = 5 +const perLoop = 1 << perLoopBits + +func main() { + Constraint(buildtags.Not("appengine").ToConstraint()) + Constraint(buildtags.Not("noasm").ToConstraint()) + Constraint(buildtags.Not("nogen").ToConstraint()) + Constraint(buildtags.Term("gc").ToConstraint()) + + for i := 1; i <= inputMax; i++ { + for j := 1; j <= outputMax; j++ { + //genMulAvx2(fmt.Sprintf("mulAvxTwoXor_%dx%d", i, j), i, j, true) + genMulAvx2(fmt.Sprintf("mulAvxTwo_%dx%d", i, j), i, j, false) + } + } + f, err := os.Create("galois_gen_switch_amd64.go") + if err != nil { + panic(err) + } + defer f.Close() + w := bufio.NewWriter(f) + defer w.Flush() + w.WriteString(`// Code generated by command: go generate ` + os.Getenv("GOFILE") + `. DO NOT EDIT. + +// +build !appengine +// +build !noasm +// +build gc +// +build !nogen + +package reedsolomon + +import "fmt" + +`) + + w.WriteString("const avx2CodeGen = true\n") + w.WriteString(fmt.Sprintf("const maxAvx2Inputs = %d\nconst maxAvx2Outputs = %d\n", inputMax, outputMax)) + w.WriteString(` + +func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int { + n := stop-start +`) + + w.WriteString(fmt.Sprintf("n = (n>>%d)<<%d\n\n", perLoopBits, perLoopBits)) + w.WriteString(`switch len(in) { +`) + for in, defs := range switchDefs[:] { + w.WriteString(fmt.Sprintf(" case %d:\n switch len(out) {\n", in+1)) + for out, def := range defs[:] { + w.WriteString(fmt.Sprintf(" case %d:\n", out+1)) + w.WriteString(def) + } + w.WriteString("}\n") + } + w.WriteString(`} + panic(fmt.Sprintf("unhandled size: %dx%d", len(in), len(out))) +} +`) + Generate() +} + +func genMulAvx2(name string, inputs int, outputs int, xor bool) { + total := inputs * outputs + + doc := []string{ + fmt.Sprintf("%s takes %d inputs and produces %d outputs.", name, inputs, outputs), + } + if !xor { + doc = append(doc, "The output is initialized to 0.") + } + + // Load shuffle masks on every use. + var loadNone bool + // Use registers for destination registers. + var regDst = true + + // lo, hi, 1 in, 1 out, 2 tmp, 1 mask + est := total*2 + outputs + 5 + if outputs == 1 { + // We don't need to keep a copy of the input if only 1 output. + est -= 2 + } + + if est > 16 { + loadNone = true + // We run out of GP registers first, now. + if inputs+outputs > 12 { + regDst = false + } + } + + TEXT(name, 0, fmt.Sprintf("func(matrix []byte, in [][]byte, out [][]byte, start, n int)")) + + // SWITCH DEFINITION: + s := fmt.Sprintf(" mulAvxTwo_%dx%d(matrix, in, out, start, n)\n", inputs, outputs) + s += fmt.Sprintf("\t\t\t\treturn n\n") + switchDefs[inputs-1][outputs-1] = s + + if loadNone { + Comment("Loading no tables to registers") + } else { + // loadNone == false + Comment("Loading all tables to registers") + } + + Doc(doc...) + Pragma("noescape") + Commentf("Full registers estimated %d YMM used", est) + + length := Load(Param("n"), GP64()) + matrixBase := GP64() + MOVQ(Param("matrix").Base().MustAddr(), matrixBase) + SHRQ(U8(perLoopBits), length) + TESTQ(length, length) + JZ(LabelRef(name + "_end")) + + dst := make([]reg.VecVirtual, outputs) + dstPtr := make([]reg.GPVirtual, outputs) + outBase := Param("out").Base().MustAddr() + outSlicePtr := GP64() + MOVQ(outBase, outSlicePtr) + for i := range dst { + dst[i] = YMM() + if !regDst { + continue + } + ptr := GP64() + MOVQ(Mem{Base: outSlicePtr, Disp: i * 24}, ptr) + dstPtr[i] = ptr + } + + inLo := make([]reg.VecVirtual, total) + inHi := make([]reg.VecVirtual, total) + + for i := range inLo { + if loadNone { + break + } + tableLo := YMM() + tableHi := YMM() + VMOVDQU(Mem{Base: matrixBase, Disp: i * 64}, tableLo) + VMOVDQU(Mem{Base: matrixBase, Disp: i*64 + 32}, tableHi) + inLo[i] = tableLo + inHi[i] = tableHi + } + + inPtrs := make([]reg.GPVirtual, inputs) + inSlicePtr := GP64() + MOVQ(Param("in").Base().MustAddr(), inSlicePtr) + for i := range inPtrs { + ptr := GP64() + MOVQ(Mem{Base: inSlicePtr, Disp: i * 24}, ptr) + inPtrs[i] = ptr + } + + tmpMask := GP64() + MOVQ(U32(15), tmpMask) + lowMask := YMM() + MOVQ(tmpMask, lowMask.AsX()) + VPBROADCASTB(lowMask.AsX(), lowMask) + + offset := GP64() + MOVQ(Param("start").MustAddr(), offset) + Label(name + "_loop") + if xor { + Commentf("Load %d outputs", outputs) + } else { + Commentf("Clear %d outputs", outputs) + } + for i := range dst { + if xor { + if regDst { + VMOVDQU(Mem{Base: dstPtr[i], Index: offset, Scale: 1}, dst[i]) + continue + } + ptr := GP64() + MOVQ(outBase, ptr) + VMOVDQU(Mem{Base: ptr, Index: offset, Scale: 1}, dst[i]) + } else { + VPXOR(dst[i], dst[i], dst[i]) + } + } + + lookLow, lookHigh := YMM(), YMM() + inLow, inHigh := YMM(), YMM() + for i := range inPtrs { + Commentf("Load and process 32 bytes from input %d to %d outputs", i, outputs) + VMOVDQU(Mem{Base: inPtrs[i], Index: offset, Scale: 1}, inLow) + VPSRLQ(U8(4), inLow, inHigh) + VPAND(lowMask, inLow, inLow) + VPAND(lowMask, inHigh, inHigh) + for j := range dst { + if loadNone { + VMOVDQU(Mem{Base: matrixBase, Disp: 64 * (i*outputs + j)}, lookLow) + VMOVDQU(Mem{Base: matrixBase, Disp: 32 + 64*(i*outputs+j)}, lookHigh) + VPSHUFB(inLow, lookLow, lookLow) + VPSHUFB(inHigh, lookHigh, lookHigh) + } else { + VPSHUFB(inLow, inLo[i*outputs+j], lookLow) + VPSHUFB(inHigh, inHi[i*outputs+j], lookHigh) + } + VPXOR(lookLow, lookHigh, lookLow) + VPXOR(lookLow, dst[j], dst[j]) + } + } + Commentf("Store %d outputs", outputs) + for i := range dst { + if regDst { + VMOVDQU(dst[i], Mem{Base: dstPtr[i], Index: offset, Scale: 1}) + continue + } + ptr := GP64() + MOVQ(Mem{Base: outSlicePtr, Disp: i * 24}, ptr) + VMOVDQU(dst[i], Mem{Base: ptr, Index: offset, Scale: 1}) + } + Comment("Prepare for next loop") + ADDQ(U8(perLoop), offset) + DECQ(length) + JNZ(LabelRef(name + "_loop")) + VZEROUPPER() + + Label(name + "_end") + RET() +} diff --git a/vendor/github.com/klauspost/reedsolomon/go.mod b/vendor/github.com/klauspost/reedsolomon/go.mod new file mode 100644 index 0000000..a059d86 --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/go.mod @@ -0,0 +1,7 @@ +module github.com/klauspost/reedsolomon + +go 1.14 + +require ( + github.com/klauspost/cpuid v1.2.4 +) diff --git a/vendor/github.com/klauspost/reedsolomon/go.sum b/vendor/github.com/klauspost/reedsolomon/go.sum new file mode 100644 index 0000000..5a44d81 --- /dev/null +++ b/vendor/github.com/klauspost/reedsolomon/go.sum @@ -0,0 +1,2 @@ +github.com/klauspost/cpuid v1.2.4 h1:EBfaK0SWSwk+fgk6efYFWdzl8MwRWoOO1gkmiaTXPW4= +github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 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/build/attr.go b/vendor/github.com/mmcloughlin/avo/build/attr.go new file mode 100644 index 0000000..1a9870b --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/attr.go @@ -0,0 +1,18 @@ +package build + +import "github.com/mmcloughlin/avo/attr" + +// TEXT and DATA attribute values included for convenience. +const ( + NOPROF = attr.NOPROF + DUPOK = attr.DUPOK + NOSPLIT = attr.NOSPLIT + RODATA = attr.RODATA + NOPTR = attr.NOPTR + WRAPPER = attr.WRAPPER + NEEDCTXT = attr.NEEDCTXT + TLSBSS = attr.TLSBSS + NOFRAME = attr.NOFRAME + REFLECTMETHOD = attr.REFLECTMETHOD + TOPFRAME = attr.TOPFRAME +) diff --git a/vendor/github.com/mmcloughlin/avo/build/cli.go b/vendor/github.com/mmcloughlin/avo/build/cli.go new file mode 100644 index 0000000..8a4a379 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/cli.go @@ -0,0 +1,171 @@ +package build + +import ( + "flag" + "io" + "log" + "os" + "runtime/pprof" + + "github.com/mmcloughlin/avo/pass" + "github.com/mmcloughlin/avo/printer" +) + +// Config contains options for an avo main function. +type Config struct { + ErrOut io.Writer + MaxErrors int // max errors to report; 0 means unlimited + CPUProfile io.WriteCloser + Passes []pass.Interface +} + +// Main is the standard main function for an avo program. This extracts the +// result from the build Context (logging and exiting on error), and performs +// configured passes. +func Main(cfg *Config, context *Context) int { + diag := log.New(cfg.ErrOut, "", 0) + + if cfg.CPUProfile != nil { + defer cfg.CPUProfile.Close() + if err := pprof.StartCPUProfile(cfg.CPUProfile); err != nil { + diag.Println("could not start CPU profile: ", err) + return 1 + } + defer pprof.StopCPUProfile() + } + + f, err := context.Result() + if err != nil { + LogError(diag, err, cfg.MaxErrors) + return 1 + } + + p := pass.Concat(cfg.Passes...) + if err := p.Execute(f); err != nil { + diag.Println(err) + return 1 + } + + return 0 +} + +// Flags represents CLI flags for an avo program. +type Flags struct { + errout *outputValue + allerrors bool + cpuprof *outputValue + pkg string + printers []*printerValue +} + +// NewFlags initializes avo flags for the given FlagSet. +func NewFlags(fs *flag.FlagSet) *Flags { + f := &Flags{} + + f.errout = newOutputValue(os.Stderr) + fs.Var(f.errout, "log", "diagnostics output") + + fs.BoolVar(&f.allerrors, "e", false, "no limit on number of errors reported") + + f.cpuprof = newOutputValue(nil) + fs.Var(f.cpuprof, "cpuprofile", "write cpu profile to `file`") + + fs.StringVar(&f.pkg, "pkg", "", "package name (defaults to current directory name)") + + goasm := newPrinterValue(printer.NewGoAsm, os.Stdout) + fs.Var(goasm, "out", "assembly output") + f.printers = append(f.printers, goasm) + + stubs := newPrinterValue(printer.NewStubs, nil) + fs.Var(stubs, "stubs", "go stub file") + f.printers = append(f.printers, stubs) + + return f +} + +// Config builds a configuration object based on flag values. +func (f *Flags) Config() *Config { + pc := printer.NewGoRunConfig() + if f.pkg != "" { + pc.Pkg = f.pkg + } + passes := []pass.Interface{pass.Compile} + for _, pv := range f.printers { + p := pv.Build(pc) + if p != nil { + passes = append(passes, p) + } + } + + cfg := &Config{ + ErrOut: f.errout.w, + MaxErrors: 10, + CPUProfile: f.cpuprof.w, + Passes: passes, + } + + if f.allerrors { + cfg.MaxErrors = 0 + } + + return cfg +} + +type outputValue struct { + w io.WriteCloser + filename string +} + +func newOutputValue(dflt io.WriteCloser) *outputValue { + return &outputValue{w: dflt} +} + +func (o *outputValue) String() string { + if o == nil { + return "" + } + return o.filename +} + +func (o *outputValue) Set(s string) error { + o.filename = s + if s == "-" { + o.w = nopwritecloser{os.Stdout} + return nil + } + f, err := os.Create(s) + if err != nil { + return err + } + o.w = f + return nil +} + +type printerValue struct { + *outputValue + Builder printer.Builder +} + +func newPrinterValue(b printer.Builder, dflt io.WriteCloser) *printerValue { + return &printerValue{ + outputValue: newOutputValue(dflt), + Builder: b, + } +} + +func (p *printerValue) Build(cfg printer.Config) pass.Interface { + if p.outputValue.w == nil { + return nil + } + return &pass.Output{ + Writer: p.outputValue.w, + Printer: p.Builder(cfg), + } +} + +// nopwritecloser wraps a Writer and provides a null implementation of Close(). +type nopwritecloser struct { + io.Writer +} + +func (nopwritecloser) Close() error { return nil } diff --git a/vendor/github.com/mmcloughlin/avo/build/context.go b/vendor/github.com/mmcloughlin/avo/build/context.go new file mode 100644 index 0000000..beb4f60 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/context.go @@ -0,0 +1,223 @@ +package build + +import ( + "errors" + "fmt" + "go/types" + + "golang.org/x/tools/go/packages" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// Context maintains state for incrementally building an avo File. +type Context struct { + pkg *packages.Package + file *ir.File + function *ir.Function + global *ir.Global + errs ErrorList + reg.Collection +} + +// NewContext initializes an empty build Context. +func NewContext() *Context { + return &Context{ + file: ir.NewFile(), + Collection: *reg.NewCollection(), + } +} + +// Package sets the package the generated file will belong to. Required to be able to reference types in the package. +func (c *Context) Package(path string) { + cfg := &packages.Config{ + Mode: packages.NeedTypes | packages.NeedDeps | packages.NeedImports, + } + pkgs, err := packages.Load(cfg, path) + if err != nil { + c.adderror(err) + return + } + pkg := pkgs[0] + if len(pkg.Errors) > 0 { + for _, err := range pkg.Errors { + c.adderror(err) + } + return + } + c.pkg = pkg +} + +// Constraints sets build constraints for the file. +func (c *Context) Constraints(t buildtags.ConstraintsConvertable) { + cs := t.ToConstraints() + if err := cs.Validate(); err != nil { + c.adderror(err) + return + } + c.file.Constraints = cs +} + +// Constraint appends a constraint to the file's build constraints. +func (c *Context) Constraint(t buildtags.ConstraintConvertable) { + c.Constraints(append(c.file.Constraints, t.ToConstraint())) +} + +// ConstraintExpr appends a constraint to the file's build constraints. The +// constraint to add is parsed from the given expression. The expression should +// look the same as the content following "// +build " in regular build +// constraint comments. +func (c *Context) ConstraintExpr(expr string) { + constraint, err := buildtags.ParseConstraint(expr) + if err != nil { + c.adderror(err) + return + } + c.Constraint(constraint) +} + +// Function starts building a new function with the given name. +func (c *Context) Function(name string) { + c.function = ir.NewFunction(name) + c.file.AddSection(c.function) +} + +// Doc sets documentation comment lines for the currently active function. +func (c *Context) Doc(lines ...string) { + c.activefunc().Doc = lines +} + +// Pragma adds a compiler directive to the currently active function. +func (c *Context) Pragma(directive string, args ...string) { + c.activefunc().AddPragma(directive, args...) +} + +// Attributes sets function attributes for the currently active function. +func (c *Context) Attributes(a attr.Attribute) { + c.activefunc().Attributes = a +} + +// Signature sets the signature for the currently active function. +func (c *Context) Signature(s *gotypes.Signature) { + c.activefunc().SetSignature(s) +} + +// SignatureExpr parses the signature expression and sets it as the active function's signature. +func (c *Context) SignatureExpr(expr string) { + s, err := gotypes.ParseSignatureInPackage(c.types(), expr) + if err != nil { + c.adderror(err) + return + } + c.Signature(s) +} + +// Implement starts building a function of the given name, whose type is +// specified by a stub in the containing package. +func (c *Context) Implement(name string) { + pkg := c.types() + if pkg == nil { + c.adderrormessage("no package specified") + return + } + s, err := gotypes.LookupSignature(pkg, name) + if err != nil { + c.adderror(err) + return + } + c.Function(name) + c.Signature(s) +} + +func (c *Context) types() *types.Package { + if c.pkg == nil { + return nil + } + return c.pkg.Types +} + +// AllocLocal allocates size bytes in the stack of the currently active function. +// Returns a reference to the base pointer for the newly allocated region. +func (c *Context) AllocLocal(size int) operand.Mem { + return c.activefunc().AllocLocal(size) +} + +// Instruction adds an instruction to the active function. +func (c *Context) Instruction(i *ir.Instruction) { + c.activefunc().AddInstruction(i) +} + +// Label adds a label to the active function. +func (c *Context) Label(name string) { + c.activefunc().AddLabel(ir.Label(name)) +} + +// Comment adds comment lines to the active function. +func (c *Context) Comment(lines ...string) { + c.activefunc().AddComment(lines...) +} + +// Commentf adds a formtted comment line. +func (c *Context) Commentf(format string, a ...interface{}) { + c.Comment(fmt.Sprintf(format, a...)) +} + +func (c *Context) activefunc() *ir.Function { + if c.function == nil { + c.adderrormessage("no active function") + return ir.NewFunction("") + } + return c.function +} + +//go:generate avogen -output zinstructions.go build + +// StaticGlobal adds a new static data section to the file and returns a pointer to it. +func (c *Context) StaticGlobal(name string) operand.Mem { + c.global = ir.NewStaticGlobal(name) + c.file.AddSection(c.global) + return c.global.Base() +} + +// DataAttributes sets the attributes on the current active global data section. +func (c *Context) DataAttributes(a attr.Attribute) { + c.activeglobal().Attributes = a +} + +// AddDatum adds constant v at offset to the current active global data section. +func (c *Context) AddDatum(offset int, v operand.Constant) { + if err := c.activeglobal().AddDatum(ir.NewDatum(offset, v)); err != nil { + c.adderror(err) + } +} + +// AppendDatum appends a constant to the current active global data section. +func (c *Context) AppendDatum(v operand.Constant) { + c.activeglobal().Append(v) +} + +func (c *Context) activeglobal() *ir.Global { + if c.global == nil { + c.adderrormessage("no active global") + return ir.NewStaticGlobal("") + } + return c.global +} + +func (c *Context) adderror(err error) { + c.errs.addext(err) +} + +func (c *Context) adderrormessage(msg string) { + c.adderror(errors.New(msg)) +} + +// Result returns the built file and any accumulated errors. +func (c *Context) Result() (*ir.File, error) { + return c.file, c.errs.Err() +} diff --git a/vendor/github.com/mmcloughlin/avo/build/doc.go b/vendor/github.com/mmcloughlin/avo/build/doc.go new file mode 100644 index 0000000..8b9a604 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/doc.go @@ -0,0 +1,2 @@ +// Package build provides an assembly-like interface for incremental building of avo Files. +package build diff --git a/vendor/github.com/mmcloughlin/avo/build/error.go b/vendor/github.com/mmcloughlin/avo/build/error.go new file mode 100644 index 0000000..1da00cb --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/error.go @@ -0,0 +1,88 @@ +package build + +import ( + "fmt" + "log" + + "github.com/mmcloughlin/avo/internal/stack" + "github.com/mmcloughlin/avo/src" +) + +// Error represents an error during building, optionally tagged with the position at which it happened. +type Error struct { + Position src.Position + Err error +} + +// exterr constructs an Error with position derived from the first frame in the +// call stack outside this package. +func exterr(err error) Error { + e := Error{Err: err} + if f := stack.ExternalCaller(); f != nil { + e.Position = src.FramePosition(*f).Relwd() + } + return e +} + +func (e Error) Error() string { + msg := e.Err.Error() + if e.Position.IsValid() { + return e.Position.String() + ": " + msg + } + return msg +} + +// ErrorList is a collection of errors for a source file. +type ErrorList []Error + +// Add appends an error to the list. +func (e *ErrorList) Add(err Error) { + *e = append(*e, err) +} + +// AddAt appends an error at position p. +func (e *ErrorList) AddAt(p src.Position, err error) { + e.Add(Error{p, err}) +} + +// addext appends an error to the list, tagged with the +func (e *ErrorList) addext(err error) { + e.Add(exterr(err)) +} + +// Err returns an error equivalent to this error list. +// If the list is empty, Err returns nil. +func (e ErrorList) Err() error { + if len(e) == 0 { + return nil + } + return e +} + +// An ErrorList implements the error interface. +func (e ErrorList) Error() string { + switch len(e) { + case 0: + return "no errors" + case 1: + return e[0].Error() + } + return fmt.Sprintf("%s (and %d more errors)", e[0], len(e)-1) +} + +// LogError logs a list of errors, one error per line, if the err parameter is +// an ErrorList. Otherwise it just logs the err string. Reports at most max +// errors, or unlimited if max is 0. +func LogError(l *log.Logger, err error, max int) { + if list, ok := err.(ErrorList); ok { + for i, e := range list { + if max > 0 && i == max { + l.Print("too many errors") + return + } + l.Printf("%s\n", e) + } + } else if err != nil { + l.Printf("%s\n", err) + } +} diff --git a/vendor/github.com/mmcloughlin/avo/build/global.go b/vendor/github.com/mmcloughlin/avo/build/global.go new file mode 100644 index 0000000..162ca7e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/global.go @@ -0,0 +1,155 @@ +package build + +import ( + "flag" + "os" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + + "github.com/mmcloughlin/avo/reg" +) + +// ctx provides a global build context. +var ctx = NewContext() + +// TEXT starts building a new function called name, with attributes a, and sets its signature (see SignatureExpr). +func TEXT(name string, a attr.Attribute, signature string) { + ctx.Function(name) + ctx.Attributes(a) + ctx.SignatureExpr(signature) +} + +// GLOBL declares a new static global data section with the given attributes. +func GLOBL(name string, a attr.Attribute) operand.Mem { + // TODO(mbm): should this be static? + g := ctx.StaticGlobal(name) + ctx.DataAttributes(a) + return g +} + +// DATA adds a data value to the active data section. +func DATA(offset int, v operand.Constant) { + ctx.AddDatum(offset, v) +} + +var flags = NewFlags(flag.CommandLine) + +// Generate builds and compiles the avo file built with the global context. This +// should be the final line of any avo program. Configuration is determined from command-line flags. +func Generate() { + if !flag.Parsed() { + flag.Parse() + } + cfg := flags.Config() + + status := Main(cfg, ctx) + + // To record coverage of integration tests we wrap main() functions in a test + // functions. In this case we need the main function to terminate, therefore we + // only exit for failure status codes. + if status != 0 { + os.Exit(status) + } +} + +// Package sets the package the generated file will belong to. Required to be able to reference types in the package. +func Package(path string) { ctx.Package(path) } + +// Constraints sets build constraints for the file. +func Constraints(t buildtags.ConstraintsConvertable) { ctx.Constraints(t) } + +// Constraint appends a constraint to the file's build constraints. +func Constraint(t buildtags.ConstraintConvertable) { ctx.Constraint(t) } + +// ConstraintExpr appends a constraint to the file's build constraints. The +// constraint to add is parsed from the given expression. The expression should +// look the same as the content following "// +build " in regular build +// constraint comments. +func ConstraintExpr(expr string) { ctx.ConstraintExpr(expr) } + +// GP8L allocates and returns a general-purpose 8-bit register (low byte). +func GP8L() reg.GPVirtual { return ctx.GP8L() } + +// GP8H allocates and returns a general-purpose 8-bit register (high byte). +func GP8H() reg.GPVirtual { return ctx.GP8H() } + +// GP8 allocates and returns a general-purpose 8-bit register (low byte). +func GP8() reg.GPVirtual { return ctx.GP8() } + +// GP16 allocates and returns a general-purpose 16-bit register. +func GP16() reg.GPVirtual { return ctx.GP16() } + +// GP32 allocates and returns a general-purpose 32-bit register. +func GP32() reg.GPVirtual { return ctx.GP32() } + +// GP64 allocates and returns a general-purpose 64-bit register. +func GP64() reg.GPVirtual { return ctx.GP64() } + +// XMM allocates and returns a 128-bit vector register. +func XMM() reg.VecVirtual { return ctx.XMM() } + +// YMM allocates and returns a 256-bit vector register. +func YMM() reg.VecVirtual { return ctx.YMM() } + +// ZMM allocates and returns a 512-bit vector register. +func ZMM() reg.VecVirtual { return ctx.ZMM() } + +// Param returns a the named argument of the active function. +func Param(name string) gotypes.Component { return ctx.Param(name) } + +// ParamIndex returns the ith argument of the active function. +func ParamIndex(i int) gotypes.Component { return ctx.ParamIndex(i) } + +// Return returns a the named return value of the active function. +func Return(name string) gotypes.Component { return ctx.Return(name) } + +// ReturnIndex returns the ith argument of the active function. +func ReturnIndex(i int) gotypes.Component { return ctx.ReturnIndex(i) } + +// Load the function argument src into register dst. Returns the destination +// register. This is syntactic sugar: it will attempt to select the right MOV +// instruction based on the types involved. +func Load(src gotypes.Component, dst reg.Register) reg.Register { return ctx.Load(src, dst) } + +// Store register src into return value dst. This is syntactic sugar: it will +// attempt to select the right MOV instruction based on the types involved. +func Store(src reg.Register, dst gotypes.Component) { ctx.Store(src, dst) } + +// Dereference loads a pointer and returns its element type. +func Dereference(ptr gotypes.Component) gotypes.Component { return ctx.Dereference(ptr) } + +// Doc sets documentation comment lines for the currently active function. +func Doc(lines ...string) { ctx.Doc(lines...) } + +// Pragma adds a compiler directive to the currently active function. +func Pragma(directive string, args ...string) { ctx.Pragma(directive, args...) } + +// Attributes sets function attributes for the currently active function. +func Attributes(a attr.Attribute) { ctx.Attributes(a) } + +// Implement starts building a function of the given name, whose type is +// specified by a stub in the containing package. +func Implement(name string) { ctx.Implement(name) } + +// AllocLocal allocates size bytes in the stack of the currently active function. +// Returns a reference to the base pointer for the newly allocated region. +func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) } + +// Label adds a label to the active function. +func Label(name string) { ctx.Label(name) } + +// Comment adds comment lines to the active function. +func Comment(lines ...string) { ctx.Comment(lines...) } + +// Commentf adds a formtted comment line. +func Commentf(format string, a ...interface{}) { ctx.Commentf(format, a...) } + +// ConstData builds a static data section containing just the given constant. +func ConstData(name string, v operand.Constant) operand.Mem { return ctx.ConstData(name, v) } + +// Instruction adds an instruction to the active function. +func Instruction(i *ir.Instruction) { ctx.Instruction(i) } diff --git a/vendor/github.com/mmcloughlin/avo/build/pseudo.go b/vendor/github.com/mmcloughlin/avo/build/pseudo.go new file mode 100644 index 0000000..83a570e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/pseudo.go @@ -0,0 +1,70 @@ +package build + +import ( + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" + + "github.com/mmcloughlin/avo/gotypes" +) + +//go:generate avogen -output zmov.go mov + +// Param returns a the named argument of the active function. +func (c *Context) Param(name string) gotypes.Component { + return c.activefunc().Signature.Params().Lookup(name) +} + +// ParamIndex returns the ith argument of the active function. +func (c *Context) ParamIndex(i int) gotypes.Component { + return c.activefunc().Signature.Params().At(i) +} + +// Return returns a the named return value of the active function. +func (c *Context) Return(name string) gotypes.Component { + return c.activefunc().Signature.Results().Lookup(name) +} + +// ReturnIndex returns the ith argument of the active function. +func (c *Context) ReturnIndex(i int) gotypes.Component { + return c.activefunc().Signature.Results().At(i) +} + +// Load the function argument src into register dst. Returns the destination +// register. This is syntactic sugar: it will attempt to select the right MOV +// instruction based on the types involved. +func (c *Context) Load(src gotypes.Component, dst reg.Register) reg.Register { + b, err := src.Resolve() + if err != nil { + c.adderror(err) + return dst + } + c.mov(b.Addr, dst, int(gotypes.Sizes.Sizeof(b.Type)), int(dst.Size()), b.Type) + return dst +} + +// Store register src into return value dst. This is syntactic sugar: it will +// attempt to select the right MOV instruction based on the types involved. +func (c *Context) Store(src reg.Register, dst gotypes.Component) { + b, err := dst.Resolve() + if err != nil { + c.adderror(err) + return + } + c.mov(src, b.Addr, int(src.Size()), int(gotypes.Sizes.Sizeof(b.Type)), b.Type) +} + +// Dereference loads a pointer and returns its element type. +func (c *Context) Dereference(ptr gotypes.Component) gotypes.Component { + r := c.GP64() + c.Load(ptr, r) + return ptr.Dereference(r) +} + +// ConstData builds a static data section containing just the given constant. +func (c *Context) ConstData(name string, v operand.Constant) operand.Mem { + g := c.StaticGlobal(name) + c.DataAttributes(attr.RODATA | attr.NOPTR) + c.AppendDatum(v) + return g +} diff --git a/vendor/github.com/mmcloughlin/avo/build/zinstructions.go b/vendor/github.com/mmcloughlin/avo/build/zinstructions.go new file mode 100644 index 0000000..33c2085 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/zinstructions.go @@ -0,0 +1,26315 @@ +// Code generated by command: avogen -output zinstructions.go build. DO NOT EDIT. + +package build + +import ( + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/x86" +) + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +// Construct and append a ADCB instruction to the active function. +func (c *Context) ADCB(imr, amr operand.Op) { + if inst, err := x86.ADCB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +// Construct and append a ADCB instruction to the active function. +// Operates on the global context. +func ADCB(imr, amr operand.Op) { ctx.ADCB(imr, amr) } + +// 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 +// Construct and append a ADCL instruction to the active function. +func (c *Context) ADCL(imr, emr operand.Op) { + if inst, err := x86.ADCL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADCL instruction to the active function. +// Operates on the global context. +func ADCL(imr, emr operand.Op) { ctx.ADCL(imr, emr) } + +// 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 +// Construct and append a ADCQ instruction to the active function. +func (c *Context) ADCQ(imr, mr operand.Op) { + if inst, err := x86.ADCQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADCQ instruction to the active function. +// Operates on the global context. +func ADCQ(imr, mr operand.Op) { ctx.ADCQ(imr, mr) } + +// 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 +// Construct and append a ADCW instruction to the active function. +func (c *Context) ADCW(imr, amr operand.Op) { + if inst, err := x86.ADCW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADCW instruction to the active function. +// Operates on the global context. +func ADCW(imr, amr operand.Op) { ctx.ADCW(imr, amr) } + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +// Construct and append a ADCXL instruction to the active function. +func (c *Context) ADCXL(mr, r operand.Op) { + if inst, err := x86.ADCXL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +// Construct and append a ADCXL instruction to the active function. +// Operates on the global context. +func ADCXL(mr, r operand.Op) { ctx.ADCXL(mr, r) } + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +// Construct and append a ADCXQ instruction to the active function. +func (c *Context) ADCXQ(mr, r operand.Op) { + if inst, err := x86.ADCXQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +// Construct and append a ADCXQ instruction to the active function. +// Operates on the global context. +func ADCXQ(mr, r operand.Op) { ctx.ADCXQ(mr, r) } + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +// Construct and append a ADDB instruction to the active function. +func (c *Context) ADDB(imr, amr operand.Op) { + if inst, err := x86.ADDB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +// Construct and append a ADDB instruction to the active function. +// Operates on the global context. +func ADDB(imr, amr operand.Op) { ctx.ADDB(imr, amr) } + +// 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 +// Construct and append a ADDL instruction to the active function. +func (c *Context) ADDL(imr, emr operand.Op) { + if inst, err := x86.ADDL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADDL instruction to the active function. +// Operates on the global context. +func ADDL(imr, emr operand.Op) { ctx.ADDL(imr, emr) } + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +// Construct and append a ADDPD instruction to the active function. +func (c *Context) ADDPD(mx, x operand.Op) { + if inst, err := x86.ADDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +// Construct and append a ADDPD instruction to the active function. +// Operates on the global context. +func ADDPD(mx, x operand.Op) { ctx.ADDPD(mx, x) } + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +// Construct and append a ADDPS instruction to the active function. +func (c *Context) ADDPS(mx, x operand.Op) { + if inst, err := x86.ADDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +// Construct and append a ADDPS instruction to the active function. +// Operates on the global context. +func ADDPS(mx, x operand.Op) { ctx.ADDPS(mx, x) } + +// 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 +// Construct and append a ADDQ instruction to the active function. +func (c *Context) ADDQ(imr, mr operand.Op) { + if inst, err := x86.ADDQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADDQ instruction to the active function. +// Operates on the global context. +func ADDQ(imr, mr operand.Op) { ctx.ADDQ(imr, mr) } + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +// Construct and append a ADDSD instruction to the active function. +func (c *Context) ADDSD(mx, x operand.Op) { + if inst, err := x86.ADDSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +// Construct and append a ADDSD instruction to the active function. +// Operates on the global context. +func ADDSD(mx, x operand.Op) { ctx.ADDSD(mx, x) } + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +// Construct and append a ADDSS instruction to the active function. +func (c *Context) ADDSS(mx, x operand.Op) { + if inst, err := x86.ADDSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +// Construct and append a ADDSS instruction to the active function. +// Operates on the global context. +func ADDSS(mx, x operand.Op) { ctx.ADDSS(mx, x) } + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +// Construct and append a ADDSUBPD instruction to the active function. +func (c *Context) ADDSUBPD(mx, x operand.Op) { + if inst, err := x86.ADDSUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +// Construct and append a ADDSUBPD instruction to the active function. +// Operates on the global context. +func ADDSUBPD(mx, x operand.Op) { ctx.ADDSUBPD(mx, x) } + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +// Construct and append a ADDSUBPS instruction to the active function. +func (c *Context) ADDSUBPS(mx, x operand.Op) { + if inst, err := x86.ADDSUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +// Construct and append a ADDSUBPS instruction to the active function. +// Operates on the global context. +func ADDSUBPS(mx, x operand.Op) { ctx.ADDSUBPS(mx, x) } + +// 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 +// Construct and append a ADDW instruction to the active function. +func (c *Context) ADDW(imr, amr operand.Op) { + if inst, err := x86.ADDW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ADDW instruction to the active function. +// Operates on the global context. +func ADDW(imr, amr operand.Op) { ctx.ADDW(imr, amr) } + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +// Construct and append a ADOXL instruction to the active function. +func (c *Context) ADOXL(mr, r operand.Op) { + if inst, err := x86.ADOXL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +// Construct and append a ADOXL instruction to the active function. +// Operates on the global context. +func ADOXL(mr, r operand.Op) { ctx.ADOXL(mr, r) } + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +// Construct and append a ADOXQ instruction to the active function. +func (c *Context) ADOXQ(mr, r operand.Op) { + if inst, err := x86.ADOXQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +// Construct and append a ADOXQ instruction to the active function. +// Operates on the global context. +func ADOXQ(mr, r operand.Op) { ctx.ADOXQ(mr, r) } + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +// Construct and append a AESDEC instruction to the active function. +func (c *Context) AESDEC(mx, x operand.Op) { + if inst, err := x86.AESDEC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +// Construct and append a AESDEC instruction to the active function. +// Operates on the global context. +func AESDEC(mx, x operand.Op) { ctx.AESDEC(mx, x) } + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +// Construct and append a AESDECLAST instruction to the active function. +func (c *Context) AESDECLAST(mx, x operand.Op) { + if inst, err := x86.AESDECLAST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +// Construct and append a AESDECLAST instruction to the active function. +// Operates on the global context. +func AESDECLAST(mx, x operand.Op) { ctx.AESDECLAST(mx, x) } + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +// Construct and append a AESENC instruction to the active function. +func (c *Context) AESENC(mx, x operand.Op) { + if inst, err := x86.AESENC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +// Construct and append a AESENC instruction to the active function. +// Operates on the global context. +func AESENC(mx, x operand.Op) { ctx.AESENC(mx, x) } + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +// Construct and append a AESENCLAST instruction to the active function. +func (c *Context) AESENCLAST(mx, x operand.Op) { + if inst, err := x86.AESENCLAST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +// Construct and append a AESENCLAST instruction to the active function. +// Operates on the global context. +func AESENCLAST(mx, x operand.Op) { ctx.AESENCLAST(mx, x) } + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +// Construct and append a AESIMC instruction to the active function. +func (c *Context) AESIMC(mx, x operand.Op) { + if inst, err := x86.AESIMC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +// Construct and append a AESIMC instruction to the active function. +// Operates on the global context. +func AESIMC(mx, x operand.Op) { ctx.AESIMC(mx, x) } + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +// Construct and append a AESKEYGENASSIST instruction to the active function. +func (c *Context) AESKEYGENASSIST(i, mx, x operand.Op) { + if inst, err := x86.AESKEYGENASSIST(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +// Construct and append a AESKEYGENASSIST instruction to the active function. +// Operates on the global context. +func AESKEYGENASSIST(i, mx, x operand.Op) { ctx.AESKEYGENASSIST(i, mx, x) } + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +// Construct and append a ANDB instruction to the active function. +func (c *Context) ANDB(imr, amr operand.Op) { + if inst, err := x86.ANDB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +// Construct and append a ANDB instruction to the active function. +// Operates on the global context. +func ANDB(imr, amr operand.Op) { ctx.ANDB(imr, amr) } + +// 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 +// Construct and append a ANDL instruction to the active function. +func (c *Context) ANDL(imr, emr operand.Op) { + if inst, err := x86.ANDL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ANDL instruction to the active function. +// Operates on the global context. +func ANDL(imr, emr operand.Op) { ctx.ANDL(imr, emr) } + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +// Construct and append a ANDNL instruction to the active function. +func (c *Context) ANDNL(mr, r, r1 operand.Op) { + if inst, err := x86.ANDNL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +// Construct and append a ANDNL instruction to the active function. +// Operates on the global context. +func ANDNL(mr, r, r1 operand.Op) { ctx.ANDNL(mr, r, r1) } + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +// Construct and append a ANDNPD instruction to the active function. +func (c *Context) ANDNPD(mx, x operand.Op) { + if inst, err := x86.ANDNPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +// Construct and append a ANDNPD instruction to the active function. +// Operates on the global context. +func ANDNPD(mx, x operand.Op) { ctx.ANDNPD(mx, x) } + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +// Construct and append a ANDNPS instruction to the active function. +func (c *Context) ANDNPS(mx, x operand.Op) { + if inst, err := x86.ANDNPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +// Construct and append a ANDNPS instruction to the active function. +// Operates on the global context. +func ANDNPS(mx, x operand.Op) { ctx.ANDNPS(mx, x) } + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +// Construct and append a ANDNQ instruction to the active function. +func (c *Context) ANDNQ(mr, r, r1 operand.Op) { + if inst, err := x86.ANDNQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +// Construct and append a ANDNQ instruction to the active function. +// Operates on the global context. +func ANDNQ(mr, r, r1 operand.Op) { ctx.ANDNQ(mr, r, r1) } + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +// Construct and append a ANDPD instruction to the active function. +func (c *Context) ANDPD(mx, x operand.Op) { + if inst, err := x86.ANDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +// Construct and append a ANDPD instruction to the active function. +// Operates on the global context. +func ANDPD(mx, x operand.Op) { ctx.ANDPD(mx, x) } + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +// Construct and append a ANDPS instruction to the active function. +func (c *Context) ANDPS(mx, x operand.Op) { + if inst, err := x86.ANDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +// Construct and append a ANDPS instruction to the active function. +// Operates on the global context. +func ANDPS(mx, x operand.Op) { ctx.ANDPS(mx, x) } + +// 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 +// Construct and append a ANDQ instruction to the active function. +func (c *Context) ANDQ(imr, mr operand.Op) { + if inst, err := x86.ANDQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ANDQ instruction to the active function. +// Operates on the global context. +func ANDQ(imr, mr operand.Op) { ctx.ANDQ(imr, mr) } + +// 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 +// Construct and append a ANDW instruction to the active function. +func (c *Context) ANDW(imr, amr operand.Op) { + if inst, err := x86.ANDW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ANDW instruction to the active function. +// Operates on the global context. +func ANDW(imr, amr operand.Op) { ctx.ANDW(imr, amr) } + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +// Construct and append a BEXTRL instruction to the active function. +func (c *Context) BEXTRL(r, mr, r1 operand.Op) { + if inst, err := x86.BEXTRL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +// Construct and append a BEXTRL instruction to the active function. +// Operates on the global context. +func BEXTRL(r, mr, r1 operand.Op) { ctx.BEXTRL(r, mr, r1) } + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +// Construct and append a BEXTRQ instruction to the active function. +func (c *Context) BEXTRQ(r, mr, r1 operand.Op) { + if inst, err := x86.BEXTRQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +// Construct and append a BEXTRQ instruction to the active function. +// Operates on the global context. +func BEXTRQ(r, mr, r1 operand.Op) { ctx.BEXTRQ(r, mr, r1) } + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +// Construct and append a BLENDPD instruction to the active function. +func (c *Context) BLENDPD(i, mx, x operand.Op) { + if inst, err := x86.BLENDPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +// Construct and append a BLENDPD instruction to the active function. +// Operates on the global context. +func BLENDPD(i, mx, x operand.Op) { ctx.BLENDPD(i, mx, x) } + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +// Construct and append a BLENDPS instruction to the active function. +func (c *Context) BLENDPS(i, mx, x operand.Op) { + if inst, err := x86.BLENDPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +// Construct and append a BLENDPS instruction to the active function. +// Operates on the global context. +func BLENDPS(i, mx, x operand.Op) { ctx.BLENDPS(i, mx, x) } + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +// Construct and append a BLENDVPD instruction to the active function. +func (c *Context) BLENDVPD(x, mx, x1 operand.Op) { + if inst, err := x86.BLENDVPD(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +// Construct and append a BLENDVPD instruction to the active function. +// Operates on the global context. +func BLENDVPD(x, mx, x1 operand.Op) { ctx.BLENDVPD(x, mx, x1) } + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +// Construct and append a BLENDVPS instruction to the active function. +func (c *Context) BLENDVPS(x, mx, x1 operand.Op) { + if inst, err := x86.BLENDVPS(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +// Construct and append a BLENDVPS instruction to the active function. +// Operates on the global context. +func BLENDVPS(x, mx, x1 operand.Op) { ctx.BLENDVPS(x, mx, x1) } + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +// Construct and append a BLSIL instruction to the active function. +func (c *Context) BLSIL(mr, r operand.Op) { + if inst, err := x86.BLSIL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +// Construct and append a BLSIL instruction to the active function. +// Operates on the global context. +func BLSIL(mr, r operand.Op) { ctx.BLSIL(mr, r) } + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +// Construct and append a BLSIQ instruction to the active function. +func (c *Context) BLSIQ(mr, r operand.Op) { + if inst, err := x86.BLSIQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +// Construct and append a BLSIQ instruction to the active function. +// Operates on the global context. +func BLSIQ(mr, r operand.Op) { ctx.BLSIQ(mr, r) } + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +// Construct and append a BLSMSKL instruction to the active function. +func (c *Context) BLSMSKL(mr, r operand.Op) { + if inst, err := x86.BLSMSKL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +// Construct and append a BLSMSKL instruction to the active function. +// Operates on the global context. +func BLSMSKL(mr, r operand.Op) { ctx.BLSMSKL(mr, r) } + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +// Construct and append a BLSMSKQ instruction to the active function. +func (c *Context) BLSMSKQ(mr, r operand.Op) { + if inst, err := x86.BLSMSKQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +// Construct and append a BLSMSKQ instruction to the active function. +// Operates on the global context. +func BLSMSKQ(mr, r operand.Op) { ctx.BLSMSKQ(mr, r) } + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +// Construct and append a BLSRL instruction to the active function. +func (c *Context) BLSRL(mr, r operand.Op) { + if inst, err := x86.BLSRL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +// Construct and append a BLSRL instruction to the active function. +// Operates on the global context. +func BLSRL(mr, r operand.Op) { ctx.BLSRL(mr, r) } + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +// Construct and append a BLSRQ instruction to the active function. +func (c *Context) BLSRQ(mr, r operand.Op) { + if inst, err := x86.BLSRQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +// Construct and append a BLSRQ instruction to the active function. +// Operates on the global context. +func BLSRQ(mr, r operand.Op) { ctx.BLSRQ(mr, r) } + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +// Construct and append a BSFL instruction to the active function. +func (c *Context) BSFL(mr, r operand.Op) { + if inst, err := x86.BSFL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +// Construct and append a BSFL instruction to the active function. +// Operates on the global context. +func BSFL(mr, r operand.Op) { ctx.BSFL(mr, r) } + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +// Construct and append a BSFQ instruction to the active function. +func (c *Context) BSFQ(mr, r operand.Op) { + if inst, err := x86.BSFQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +// Construct and append a BSFQ instruction to the active function. +// Operates on the global context. +func BSFQ(mr, r operand.Op) { ctx.BSFQ(mr, r) } + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +// Construct and append a BSFW instruction to the active function. +func (c *Context) BSFW(mr, r operand.Op) { + if inst, err := x86.BSFW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +// Construct and append a BSFW instruction to the active function. +// Operates on the global context. +func BSFW(mr, r operand.Op) { ctx.BSFW(mr, r) } + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +// Construct and append a BSRL instruction to the active function. +func (c *Context) BSRL(mr, r operand.Op) { + if inst, err := x86.BSRL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +// Construct and append a BSRL instruction to the active function. +// Operates on the global context. +func BSRL(mr, r operand.Op) { ctx.BSRL(mr, r) } + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +// Construct and append a BSRQ instruction to the active function. +func (c *Context) BSRQ(mr, r operand.Op) { + if inst, err := x86.BSRQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +// Construct and append a BSRQ instruction to the active function. +// Operates on the global context. +func BSRQ(mr, r operand.Op) { ctx.BSRQ(mr, r) } + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +// Construct and append a BSRW instruction to the active function. +func (c *Context) BSRW(mr, r operand.Op) { + if inst, err := x86.BSRW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +// Construct and append a BSRW instruction to the active function. +// Operates on the global context. +func BSRW(mr, r operand.Op) { ctx.BSRW(mr, r) } + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +// Construct and append a BSWAPL instruction to the active function. +func (c *Context) BSWAPL(r operand.Op) { + if inst, err := x86.BSWAPL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +// Construct and append a BSWAPL instruction to the active function. +// Operates on the global context. +func BSWAPL(r operand.Op) { ctx.BSWAPL(r) } + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +// Construct and append a BSWAPQ instruction to the active function. +func (c *Context) BSWAPQ(r operand.Op) { + if inst, err := x86.BSWAPQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +// Construct and append a BSWAPQ instruction to the active function. +// Operates on the global context. +func BSWAPQ(r operand.Op) { ctx.BSWAPQ(r) } + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +// Construct and append a BTCL instruction to the active function. +func (c *Context) BTCL(ir, mr operand.Op) { + if inst, err := x86.BTCL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +// Construct and append a BTCL instruction to the active function. +// Operates on the global context. +func BTCL(ir, mr operand.Op) { ctx.BTCL(ir, mr) } + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +// Construct and append a BTCQ instruction to the active function. +func (c *Context) BTCQ(ir, mr operand.Op) { + if inst, err := x86.BTCQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +// Construct and append a BTCQ instruction to the active function. +// Operates on the global context. +func BTCQ(ir, mr operand.Op) { ctx.BTCQ(ir, mr) } + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +// Construct and append a BTCW instruction to the active function. +func (c *Context) BTCW(ir, mr operand.Op) { + if inst, err := x86.BTCW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +// Construct and append a BTCW instruction to the active function. +// Operates on the global context. +func BTCW(ir, mr operand.Op) { ctx.BTCW(ir, mr) } + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +// Construct and append a BTL instruction to the active function. +func (c *Context) BTL(ir, mr operand.Op) { + if inst, err := x86.BTL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +// Construct and append a BTL instruction to the active function. +// Operates on the global context. +func BTL(ir, mr operand.Op) { ctx.BTL(ir, mr) } + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +// Construct and append a BTQ instruction to the active function. +func (c *Context) BTQ(ir, mr operand.Op) { + if inst, err := x86.BTQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +// Construct and append a BTQ instruction to the active function. +// Operates on the global context. +func BTQ(ir, mr operand.Op) { ctx.BTQ(ir, mr) } + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +// Construct and append a BTRL instruction to the active function. +func (c *Context) BTRL(ir, mr operand.Op) { + if inst, err := x86.BTRL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +// Construct and append a BTRL instruction to the active function. +// Operates on the global context. +func BTRL(ir, mr operand.Op) { ctx.BTRL(ir, mr) } + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +// Construct and append a BTRQ instruction to the active function. +func (c *Context) BTRQ(ir, mr operand.Op) { + if inst, err := x86.BTRQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +// Construct and append a BTRQ instruction to the active function. +// Operates on the global context. +func BTRQ(ir, mr operand.Op) { ctx.BTRQ(ir, mr) } + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +// Construct and append a BTRW instruction to the active function. +func (c *Context) BTRW(ir, mr operand.Op) { + if inst, err := x86.BTRW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +// Construct and append a BTRW instruction to the active function. +// Operates on the global context. +func BTRW(ir, mr operand.Op) { ctx.BTRW(ir, mr) } + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +// Construct and append a BTSL instruction to the active function. +func (c *Context) BTSL(ir, mr operand.Op) { + if inst, err := x86.BTSL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +// Construct and append a BTSL instruction to the active function. +// Operates on the global context. +func BTSL(ir, mr operand.Op) { ctx.BTSL(ir, mr) } + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +// Construct and append a BTSQ instruction to the active function. +func (c *Context) BTSQ(ir, mr operand.Op) { + if inst, err := x86.BTSQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +// Construct and append a BTSQ instruction to the active function. +// Operates on the global context. +func BTSQ(ir, mr operand.Op) { ctx.BTSQ(ir, mr) } + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +// Construct and append a BTSW instruction to the active function. +func (c *Context) BTSW(ir, mr operand.Op) { + if inst, err := x86.BTSW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +// Construct and append a BTSW instruction to the active function. +// Operates on the global context. +func BTSW(ir, mr operand.Op) { ctx.BTSW(ir, mr) } + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +// Construct and append a BTW instruction to the active function. +func (c *Context) BTW(ir, mr operand.Op) { + if inst, err := x86.BTW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +// Construct and append a BTW instruction to the active function. +// Operates on the global context. +func BTW(ir, mr operand.Op) { ctx.BTW(ir, mr) } + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +// Construct and append a BZHIL instruction to the active function. +func (c *Context) BZHIL(r, mr, r1 operand.Op) { + if inst, err := x86.BZHIL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +// Construct and append a BZHIL instruction to the active function. +// Operates on the global context. +func BZHIL(r, mr, r1 operand.Op) { ctx.BZHIL(r, mr, r1) } + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +// Construct and append a BZHIQ instruction to the active function. +func (c *Context) BZHIQ(r, mr, r1 operand.Op) { + if inst, err := x86.BZHIQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +// Construct and append a BZHIQ instruction to the active function. +// Operates on the global context. +func BZHIQ(r, mr, r1 operand.Op) { ctx.BZHIQ(r, mr, r1) } + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +// Construct and append a CALL instruction to the active function. +func (c *Context) CALL(r operand.Op) { + if inst, err := x86.CALL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +// Construct and append a CALL instruction to the active function. +// Operates on the global context. +func CALL(r operand.Op) { ctx.CALL(r) } + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +// Construct and append a CBW instruction to the active function. +func (c *Context) CBW() { + if inst, err := x86.CBW(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +// Construct and append a CBW instruction to the active function. +// Operates on the global context. +func CBW() { ctx.CBW() } + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +// Construct and append a CDQ instruction to the active function. +func (c *Context) CDQ() { + if inst, err := x86.CDQ(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +// Construct and append a CDQ instruction to the active function. +// Operates on the global context. +func CDQ() { ctx.CDQ() } + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +// Construct and append a CDQE instruction to the active function. +func (c *Context) CDQE() { + if inst, err := x86.CDQE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +// Construct and append a CDQE instruction to the active function. +// Operates on the global context. +func CDQE() { ctx.CDQE() } + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +// Construct and append a CLC instruction to the active function. +func (c *Context) CLC() { + if inst, err := x86.CLC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +// Construct and append a CLC instruction to the active function. +// Operates on the global context. +func CLC() { ctx.CLC() } + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +// Construct and append a CLD instruction to the active function. +func (c *Context) CLD() { + if inst, err := x86.CLD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +// Construct and append a CLD instruction to the active function. +// Operates on the global context. +func CLD() { ctx.CLD() } + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +// Construct and append a CLFLUSH instruction to the active function. +func (c *Context) CLFLUSH(m operand.Op) { + if inst, err := x86.CLFLUSH(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +// Construct and append a CLFLUSH instruction to the active function. +// Operates on the global context. +func CLFLUSH(m operand.Op) { ctx.CLFLUSH(m) } + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +// Construct and append a CLFLUSHOPT instruction to the active function. +func (c *Context) CLFLUSHOPT(m operand.Op) { + if inst, err := x86.CLFLUSHOPT(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +// Construct and append a CLFLUSHOPT instruction to the active function. +// Operates on the global context. +func CLFLUSHOPT(m operand.Op) { ctx.CLFLUSHOPT(m) } + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +// Construct and append a CMC instruction to the active function. +func (c *Context) CMC() { + if inst, err := x86.CMC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +// Construct and append a CMC instruction to the active function. +// Operates on the global context. +func CMC() { ctx.CMC() } + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +// Construct and append a CMOVLCC instruction to the active function. +func (c *Context) CMOVLCC(mr, r operand.Op) { + if inst, err := x86.CMOVLCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +// Construct and append a CMOVLCC instruction to the active function. +// Operates on the global context. +func CMOVLCC(mr, r operand.Op) { ctx.CMOVLCC(mr, r) } + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +// Construct and append a CMOVLCS instruction to the active function. +func (c *Context) CMOVLCS(mr, r operand.Op) { + if inst, err := x86.CMOVLCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +// Construct and append a CMOVLCS instruction to the active function. +// Operates on the global context. +func CMOVLCS(mr, r operand.Op) { ctx.CMOVLCS(mr, r) } + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +// Construct and append a CMOVLEQ instruction to the active function. +func (c *Context) CMOVLEQ(mr, r operand.Op) { + if inst, err := x86.CMOVLEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +// Construct and append a CMOVLEQ instruction to the active function. +// Operates on the global context. +func CMOVLEQ(mr, r operand.Op) { ctx.CMOVLEQ(mr, r) } + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +// Construct and append a CMOVLGE instruction to the active function. +func (c *Context) CMOVLGE(mr, r operand.Op) { + if inst, err := x86.CMOVLGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +// Construct and append a CMOVLGE instruction to the active function. +// Operates on the global context. +func CMOVLGE(mr, r operand.Op) { ctx.CMOVLGE(mr, r) } + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +// Construct and append a CMOVLGT instruction to the active function. +func (c *Context) CMOVLGT(mr, r operand.Op) { + if inst, err := x86.CMOVLGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +// Construct and append a CMOVLGT instruction to the active function. +// Operates on the global context. +func CMOVLGT(mr, r operand.Op) { ctx.CMOVLGT(mr, r) } + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +// Construct and append a CMOVLHI instruction to the active function. +func (c *Context) CMOVLHI(mr, r operand.Op) { + if inst, err := x86.CMOVLHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +// Construct and append a CMOVLHI instruction to the active function. +// Operates on the global context. +func CMOVLHI(mr, r operand.Op) { ctx.CMOVLHI(mr, r) } + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +// Construct and append a CMOVLLE instruction to the active function. +func (c *Context) CMOVLLE(mr, r operand.Op) { + if inst, err := x86.CMOVLLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +// Construct and append a CMOVLLE instruction to the active function. +// Operates on the global context. +func CMOVLLE(mr, r operand.Op) { ctx.CMOVLLE(mr, r) } + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +// Construct and append a CMOVLLS instruction to the active function. +func (c *Context) CMOVLLS(mr, r operand.Op) { + if inst, err := x86.CMOVLLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +// Construct and append a CMOVLLS instruction to the active function. +// Operates on the global context. +func CMOVLLS(mr, r operand.Op) { ctx.CMOVLLS(mr, r) } + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +// Construct and append a CMOVLLT instruction to the active function. +func (c *Context) CMOVLLT(mr, r operand.Op) { + if inst, err := x86.CMOVLLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +// Construct and append a CMOVLLT instruction to the active function. +// Operates on the global context. +func CMOVLLT(mr, r operand.Op) { ctx.CMOVLLT(mr, r) } + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +// Construct and append a CMOVLMI instruction to the active function. +func (c *Context) CMOVLMI(mr, r operand.Op) { + if inst, err := x86.CMOVLMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +// Construct and append a CMOVLMI instruction to the active function. +// Operates on the global context. +func CMOVLMI(mr, r operand.Op) { ctx.CMOVLMI(mr, r) } + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +// Construct and append a CMOVLNE instruction to the active function. +func (c *Context) CMOVLNE(mr, r operand.Op) { + if inst, err := x86.CMOVLNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +// Construct and append a CMOVLNE instruction to the active function. +// Operates on the global context. +func CMOVLNE(mr, r operand.Op) { ctx.CMOVLNE(mr, r) } + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +// Construct and append a CMOVLOC instruction to the active function. +func (c *Context) CMOVLOC(mr, r operand.Op) { + if inst, err := x86.CMOVLOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +// Construct and append a CMOVLOC instruction to the active function. +// Operates on the global context. +func CMOVLOC(mr, r operand.Op) { ctx.CMOVLOC(mr, r) } + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +// Construct and append a CMOVLOS instruction to the active function. +func (c *Context) CMOVLOS(mr, r operand.Op) { + if inst, err := x86.CMOVLOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +// Construct and append a CMOVLOS instruction to the active function. +// Operates on the global context. +func CMOVLOS(mr, r operand.Op) { ctx.CMOVLOS(mr, r) } + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +// Construct and append a CMOVLPC instruction to the active function. +func (c *Context) CMOVLPC(mr, r operand.Op) { + if inst, err := x86.CMOVLPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +// Construct and append a CMOVLPC instruction to the active function. +// Operates on the global context. +func CMOVLPC(mr, r operand.Op) { ctx.CMOVLPC(mr, r) } + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +// Construct and append a CMOVLPL instruction to the active function. +func (c *Context) CMOVLPL(mr, r operand.Op) { + if inst, err := x86.CMOVLPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +// Construct and append a CMOVLPL instruction to the active function. +// Operates on the global context. +func CMOVLPL(mr, r operand.Op) { ctx.CMOVLPL(mr, r) } + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +// Construct and append a CMOVLPS instruction to the active function. +func (c *Context) CMOVLPS(mr, r operand.Op) { + if inst, err := x86.CMOVLPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +// Construct and append a CMOVLPS instruction to the active function. +// Operates on the global context. +func CMOVLPS(mr, r operand.Op) { ctx.CMOVLPS(mr, r) } + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +// Construct and append a CMOVQCC instruction to the active function. +func (c *Context) CMOVQCC(mr, r operand.Op) { + if inst, err := x86.CMOVQCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +// Construct and append a CMOVQCC instruction to the active function. +// Operates on the global context. +func CMOVQCC(mr, r operand.Op) { ctx.CMOVQCC(mr, r) } + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +// Construct and append a CMOVQCS instruction to the active function. +func (c *Context) CMOVQCS(mr, r operand.Op) { + if inst, err := x86.CMOVQCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +// Construct and append a CMOVQCS instruction to the active function. +// Operates on the global context. +func CMOVQCS(mr, r operand.Op) { ctx.CMOVQCS(mr, r) } + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +// Construct and append a CMOVQEQ instruction to the active function. +func (c *Context) CMOVQEQ(mr, r operand.Op) { + if inst, err := x86.CMOVQEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +// Construct and append a CMOVQEQ instruction to the active function. +// Operates on the global context. +func CMOVQEQ(mr, r operand.Op) { ctx.CMOVQEQ(mr, r) } + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +// Construct and append a CMOVQGE instruction to the active function. +func (c *Context) CMOVQGE(mr, r operand.Op) { + if inst, err := x86.CMOVQGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +// Construct and append a CMOVQGE instruction to the active function. +// Operates on the global context. +func CMOVQGE(mr, r operand.Op) { ctx.CMOVQGE(mr, r) } + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +// Construct and append a CMOVQGT instruction to the active function. +func (c *Context) CMOVQGT(mr, r operand.Op) { + if inst, err := x86.CMOVQGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +// Construct and append a CMOVQGT instruction to the active function. +// Operates on the global context. +func CMOVQGT(mr, r operand.Op) { ctx.CMOVQGT(mr, r) } + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +// Construct and append a CMOVQHI instruction to the active function. +func (c *Context) CMOVQHI(mr, r operand.Op) { + if inst, err := x86.CMOVQHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +// Construct and append a CMOVQHI instruction to the active function. +// Operates on the global context. +func CMOVQHI(mr, r operand.Op) { ctx.CMOVQHI(mr, r) } + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +// Construct and append a CMOVQLE instruction to the active function. +func (c *Context) CMOVQLE(mr, r operand.Op) { + if inst, err := x86.CMOVQLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +// Construct and append a CMOVQLE instruction to the active function. +// Operates on the global context. +func CMOVQLE(mr, r operand.Op) { ctx.CMOVQLE(mr, r) } + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +// Construct and append a CMOVQLS instruction to the active function. +func (c *Context) CMOVQLS(mr, r operand.Op) { + if inst, err := x86.CMOVQLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +// Construct and append a CMOVQLS instruction to the active function. +// Operates on the global context. +func CMOVQLS(mr, r operand.Op) { ctx.CMOVQLS(mr, r) } + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +// Construct and append a CMOVQLT instruction to the active function. +func (c *Context) CMOVQLT(mr, r operand.Op) { + if inst, err := x86.CMOVQLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +// Construct and append a CMOVQLT instruction to the active function. +// Operates on the global context. +func CMOVQLT(mr, r operand.Op) { ctx.CMOVQLT(mr, r) } + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +// Construct and append a CMOVQMI instruction to the active function. +func (c *Context) CMOVQMI(mr, r operand.Op) { + if inst, err := x86.CMOVQMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +// Construct and append a CMOVQMI instruction to the active function. +// Operates on the global context. +func CMOVQMI(mr, r operand.Op) { ctx.CMOVQMI(mr, r) } + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +// Construct and append a CMOVQNE instruction to the active function. +func (c *Context) CMOVQNE(mr, r operand.Op) { + if inst, err := x86.CMOVQNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +// Construct and append a CMOVQNE instruction to the active function. +// Operates on the global context. +func CMOVQNE(mr, r operand.Op) { ctx.CMOVQNE(mr, r) } + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +// Construct and append a CMOVQOC instruction to the active function. +func (c *Context) CMOVQOC(mr, r operand.Op) { + if inst, err := x86.CMOVQOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +// Construct and append a CMOVQOC instruction to the active function. +// Operates on the global context. +func CMOVQOC(mr, r operand.Op) { ctx.CMOVQOC(mr, r) } + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +// Construct and append a CMOVQOS instruction to the active function. +func (c *Context) CMOVQOS(mr, r operand.Op) { + if inst, err := x86.CMOVQOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +// Construct and append a CMOVQOS instruction to the active function. +// Operates on the global context. +func CMOVQOS(mr, r operand.Op) { ctx.CMOVQOS(mr, r) } + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +// Construct and append a CMOVQPC instruction to the active function. +func (c *Context) CMOVQPC(mr, r operand.Op) { + if inst, err := x86.CMOVQPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +// Construct and append a CMOVQPC instruction to the active function. +// Operates on the global context. +func CMOVQPC(mr, r operand.Op) { ctx.CMOVQPC(mr, r) } + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +// Construct and append a CMOVQPL instruction to the active function. +func (c *Context) CMOVQPL(mr, r operand.Op) { + if inst, err := x86.CMOVQPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +// Construct and append a CMOVQPL instruction to the active function. +// Operates on the global context. +func CMOVQPL(mr, r operand.Op) { ctx.CMOVQPL(mr, r) } + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +// Construct and append a CMOVQPS instruction to the active function. +func (c *Context) CMOVQPS(mr, r operand.Op) { + if inst, err := x86.CMOVQPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +// Construct and append a CMOVQPS instruction to the active function. +// Operates on the global context. +func CMOVQPS(mr, r operand.Op) { ctx.CMOVQPS(mr, r) } + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +// Construct and append a CMOVWCC instruction to the active function. +func (c *Context) CMOVWCC(mr, r operand.Op) { + if inst, err := x86.CMOVWCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +// Construct and append a CMOVWCC instruction to the active function. +// Operates on the global context. +func CMOVWCC(mr, r operand.Op) { ctx.CMOVWCC(mr, r) } + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +// Construct and append a CMOVWCS instruction to the active function. +func (c *Context) CMOVWCS(mr, r operand.Op) { + if inst, err := x86.CMOVWCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +// Construct and append a CMOVWCS instruction to the active function. +// Operates on the global context. +func CMOVWCS(mr, r operand.Op) { ctx.CMOVWCS(mr, r) } + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +// Construct and append a CMOVWEQ instruction to the active function. +func (c *Context) CMOVWEQ(mr, r operand.Op) { + if inst, err := x86.CMOVWEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +// Construct and append a CMOVWEQ instruction to the active function. +// Operates on the global context. +func CMOVWEQ(mr, r operand.Op) { ctx.CMOVWEQ(mr, r) } + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +// Construct and append a CMOVWGE instruction to the active function. +func (c *Context) CMOVWGE(mr, r operand.Op) { + if inst, err := x86.CMOVWGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +// Construct and append a CMOVWGE instruction to the active function. +// Operates on the global context. +func CMOVWGE(mr, r operand.Op) { ctx.CMOVWGE(mr, r) } + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +// Construct and append a CMOVWGT instruction to the active function. +func (c *Context) CMOVWGT(mr, r operand.Op) { + if inst, err := x86.CMOVWGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +// Construct and append a CMOVWGT instruction to the active function. +// Operates on the global context. +func CMOVWGT(mr, r operand.Op) { ctx.CMOVWGT(mr, r) } + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +// Construct and append a CMOVWHI instruction to the active function. +func (c *Context) CMOVWHI(mr, r operand.Op) { + if inst, err := x86.CMOVWHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +// Construct and append a CMOVWHI instruction to the active function. +// Operates on the global context. +func CMOVWHI(mr, r operand.Op) { ctx.CMOVWHI(mr, r) } + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +// Construct and append a CMOVWLE instruction to the active function. +func (c *Context) CMOVWLE(mr, r operand.Op) { + if inst, err := x86.CMOVWLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +// Construct and append a CMOVWLE instruction to the active function. +// Operates on the global context. +func CMOVWLE(mr, r operand.Op) { ctx.CMOVWLE(mr, r) } + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +// Construct and append a CMOVWLS instruction to the active function. +func (c *Context) CMOVWLS(mr, r operand.Op) { + if inst, err := x86.CMOVWLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +// Construct and append a CMOVWLS instruction to the active function. +// Operates on the global context. +func CMOVWLS(mr, r operand.Op) { ctx.CMOVWLS(mr, r) } + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +// Construct and append a CMOVWLT instruction to the active function. +func (c *Context) CMOVWLT(mr, r operand.Op) { + if inst, err := x86.CMOVWLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +// Construct and append a CMOVWLT instruction to the active function. +// Operates on the global context. +func CMOVWLT(mr, r operand.Op) { ctx.CMOVWLT(mr, r) } + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +// Construct and append a CMOVWMI instruction to the active function. +func (c *Context) CMOVWMI(mr, r operand.Op) { + if inst, err := x86.CMOVWMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +// Construct and append a CMOVWMI instruction to the active function. +// Operates on the global context. +func CMOVWMI(mr, r operand.Op) { ctx.CMOVWMI(mr, r) } + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +// Construct and append a CMOVWNE instruction to the active function. +func (c *Context) CMOVWNE(mr, r operand.Op) { + if inst, err := x86.CMOVWNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +// Construct and append a CMOVWNE instruction to the active function. +// Operates on the global context. +func CMOVWNE(mr, r operand.Op) { ctx.CMOVWNE(mr, r) } + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +// Construct and append a CMOVWOC instruction to the active function. +func (c *Context) CMOVWOC(mr, r operand.Op) { + if inst, err := x86.CMOVWOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +// Construct and append a CMOVWOC instruction to the active function. +// Operates on the global context. +func CMOVWOC(mr, r operand.Op) { ctx.CMOVWOC(mr, r) } + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +// Construct and append a CMOVWOS instruction to the active function. +func (c *Context) CMOVWOS(mr, r operand.Op) { + if inst, err := x86.CMOVWOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +// Construct and append a CMOVWOS instruction to the active function. +// Operates on the global context. +func CMOVWOS(mr, r operand.Op) { ctx.CMOVWOS(mr, r) } + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +// Construct and append a CMOVWPC instruction to the active function. +func (c *Context) CMOVWPC(mr, r operand.Op) { + if inst, err := x86.CMOVWPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +// Construct and append a CMOVWPC instruction to the active function. +// Operates on the global context. +func CMOVWPC(mr, r operand.Op) { ctx.CMOVWPC(mr, r) } + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +// Construct and append a CMOVWPL instruction to the active function. +func (c *Context) CMOVWPL(mr, r operand.Op) { + if inst, err := x86.CMOVWPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +// Construct and append a CMOVWPL instruction to the active function. +// Operates on the global context. +func CMOVWPL(mr, r operand.Op) { ctx.CMOVWPL(mr, r) } + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +// Construct and append a CMOVWPS instruction to the active function. +func (c *Context) CMOVWPS(mr, r operand.Op) { + if inst, err := x86.CMOVWPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +// Construct and append a CMOVWPS instruction to the active function. +// Operates on the global context. +func CMOVWPS(mr, r operand.Op) { ctx.CMOVWPS(mr, r) } + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +// Construct and append a CMPB instruction to the active function. +func (c *Context) CMPB(amr, imr operand.Op) { + if inst, err := x86.CMPB(amr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +// Construct and append a CMPB instruction to the active function. +// Operates on the global context. +func CMPB(amr, imr operand.Op) { ctx.CMPB(amr, imr) } + +// 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 +// Construct and append a CMPL instruction to the active function. +func (c *Context) CMPL(emr, imr operand.Op) { + if inst, err := x86.CMPL(emr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a CMPL instruction to the active function. +// Operates on the global context. +func CMPL(emr, imr operand.Op) { ctx.CMPL(emr, imr) } + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +// Construct and append a CMPPD instruction to the active function. +func (c *Context) CMPPD(mx, x, i operand.Op) { + if inst, err := x86.CMPPD(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +// Construct and append a CMPPD instruction to the active function. +// Operates on the global context. +func CMPPD(mx, x, i operand.Op) { ctx.CMPPD(mx, x, i) } + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +// Construct and append a CMPPS instruction to the active function. +func (c *Context) CMPPS(mx, x, i operand.Op) { + if inst, err := x86.CMPPS(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +// Construct and append a CMPPS instruction to the active function. +// Operates on the global context. +func CMPPS(mx, x, i operand.Op) { ctx.CMPPS(mx, x, i) } + +// 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 +// Construct and append a CMPQ instruction to the active function. +func (c *Context) CMPQ(mr, imr operand.Op) { + if inst, err := x86.CMPQ(mr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a CMPQ instruction to the active function. +// Operates on the global context. +func CMPQ(mr, imr operand.Op) { ctx.CMPQ(mr, imr) } + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +// Construct and append a CMPSD instruction to the active function. +func (c *Context) CMPSD(mx, x, i operand.Op) { + if inst, err := x86.CMPSD(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +// Construct and append a CMPSD instruction to the active function. +// Operates on the global context. +func CMPSD(mx, x, i operand.Op) { ctx.CMPSD(mx, x, i) } + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +// Construct and append a CMPSS instruction to the active function. +func (c *Context) CMPSS(mx, x, i operand.Op) { + if inst, err := x86.CMPSS(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +// Construct and append a CMPSS instruction to the active function. +// Operates on the global context. +func CMPSS(mx, x, i operand.Op) { ctx.CMPSS(mx, x, i) } + +// 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 +// Construct and append a CMPW instruction to the active function. +func (c *Context) CMPW(amr, imr operand.Op) { + if inst, err := x86.CMPW(amr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a CMPW instruction to the active function. +// Operates on the global context. +func CMPW(amr, imr operand.Op) { ctx.CMPW(amr, imr) } + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +// Construct and append a CMPXCHG16B instruction to the active function. +func (c *Context) CMPXCHG16B(m operand.Op) { + if inst, err := x86.CMPXCHG16B(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +// Construct and append a CMPXCHG16B instruction to the active function. +// Operates on the global context. +func CMPXCHG16B(m operand.Op) { ctx.CMPXCHG16B(m) } + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +// Construct and append a CMPXCHG8B instruction to the active function. +func (c *Context) CMPXCHG8B(m operand.Op) { + if inst, err := x86.CMPXCHG8B(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +// Construct and append a CMPXCHG8B instruction to the active function. +// Operates on the global context. +func CMPXCHG8B(m operand.Op) { ctx.CMPXCHG8B(m) } + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +// Construct and append a CMPXCHGB instruction to the active function. +func (c *Context) CMPXCHGB(r, mr operand.Op) { + if inst, err := x86.CMPXCHGB(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +// Construct and append a CMPXCHGB instruction to the active function. +// Operates on the global context. +func CMPXCHGB(r, mr operand.Op) { ctx.CMPXCHGB(r, mr) } + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +// Construct and append a CMPXCHGL instruction to the active function. +func (c *Context) CMPXCHGL(r, mr operand.Op) { + if inst, err := x86.CMPXCHGL(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +// Construct and append a CMPXCHGL instruction to the active function. +// Operates on the global context. +func CMPXCHGL(r, mr operand.Op) { ctx.CMPXCHGL(r, mr) } + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +// Construct and append a CMPXCHGQ instruction to the active function. +func (c *Context) CMPXCHGQ(r, mr operand.Op) { + if inst, err := x86.CMPXCHGQ(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +// Construct and append a CMPXCHGQ instruction to the active function. +// Operates on the global context. +func CMPXCHGQ(r, mr operand.Op) { ctx.CMPXCHGQ(r, mr) } + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +// Construct and append a CMPXCHGW instruction to the active function. +func (c *Context) CMPXCHGW(r, mr operand.Op) { + if inst, err := x86.CMPXCHGW(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +// Construct and append a CMPXCHGW instruction to the active function. +// Operates on the global context. +func CMPXCHGW(r, mr operand.Op) { ctx.CMPXCHGW(r, mr) } + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +// Construct and append a COMISD instruction to the active function. +func (c *Context) COMISD(mx, x operand.Op) { + if inst, err := x86.COMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +// Construct and append a COMISD instruction to the active function. +// Operates on the global context. +func COMISD(mx, x operand.Op) { ctx.COMISD(mx, x) } + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +// Construct and append a COMISS instruction to the active function. +func (c *Context) COMISS(mx, x operand.Op) { + if inst, err := x86.COMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +// Construct and append a COMISS instruction to the active function. +// Operates on the global context. +func COMISS(mx, x operand.Op) { ctx.COMISS(mx, x) } + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +// Construct and append a CPUID instruction to the active function. +func (c *Context) CPUID() { + if inst, err := x86.CPUID(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +// Construct and append a CPUID instruction to the active function. +// Operates on the global context. +func CPUID() { ctx.CPUID() } + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +// Construct and append a CQO instruction to the active function. +func (c *Context) CQO() { + if inst, err := x86.CQO(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +// Construct and append a CQO instruction to the active function. +// Operates on the global context. +func CQO() { ctx.CQO() } + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +// Construct and append a CRC32B instruction to the active function. +func (c *Context) CRC32B(mr, r operand.Op) { + if inst, err := x86.CRC32B(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +// Construct and append a CRC32B instruction to the active function. +// Operates on the global context. +func CRC32B(mr, r operand.Op) { ctx.CRC32B(mr, r) } + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +// Construct and append a CRC32L instruction to the active function. +func (c *Context) CRC32L(mr, r operand.Op) { + if inst, err := x86.CRC32L(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +// Construct and append a CRC32L instruction to the active function. +// Operates on the global context. +func CRC32L(mr, r operand.Op) { ctx.CRC32L(mr, r) } + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +// Construct and append a CRC32Q instruction to the active function. +func (c *Context) CRC32Q(mr, r operand.Op) { + if inst, err := x86.CRC32Q(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +// Construct and append a CRC32Q instruction to the active function. +// Operates on the global context. +func CRC32Q(mr, r operand.Op) { ctx.CRC32Q(mr, r) } + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +// Construct and append a CRC32W instruction to the active function. +func (c *Context) CRC32W(mr, r operand.Op) { + if inst, err := x86.CRC32W(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +// Construct and append a CRC32W instruction to the active function. +// Operates on the global context. +func CRC32W(mr, r operand.Op) { ctx.CRC32W(mr, r) } + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +// Construct and append a CVTPD2PL instruction to the active function. +func (c *Context) CVTPD2PL(mx, x operand.Op) { + if inst, err := x86.CVTPD2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +// Construct and append a CVTPD2PL instruction to the active function. +// Operates on the global context. +func CVTPD2PL(mx, x operand.Op) { ctx.CVTPD2PL(mx, x) } + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +// Construct and append a CVTPD2PS instruction to the active function. +func (c *Context) CVTPD2PS(mx, x operand.Op) { + if inst, err := x86.CVTPD2PS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +// Construct and append a CVTPD2PS instruction to the active function. +// Operates on the global context. +func CVTPD2PS(mx, x operand.Op) { ctx.CVTPD2PS(mx, x) } + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +// Construct and append a CVTPL2PD instruction to the active function. +func (c *Context) CVTPL2PD(mx, x operand.Op) { + if inst, err := x86.CVTPL2PD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +// Construct and append a CVTPL2PD instruction to the active function. +// Operates on the global context. +func CVTPL2PD(mx, x operand.Op) { ctx.CVTPL2PD(mx, x) } + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +// Construct and append a CVTPL2PS instruction to the active function. +func (c *Context) CVTPL2PS(mx, x operand.Op) { + if inst, err := x86.CVTPL2PS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +// Construct and append a CVTPL2PS instruction to the active function. +// Operates on the global context. +func CVTPL2PS(mx, x operand.Op) { ctx.CVTPL2PS(mx, x) } + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +// Construct and append a CVTPS2PD instruction to the active function. +func (c *Context) CVTPS2PD(mx, x operand.Op) { + if inst, err := x86.CVTPS2PD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +// Construct and append a CVTPS2PD instruction to the active function. +// Operates on the global context. +func CVTPS2PD(mx, x operand.Op) { ctx.CVTPS2PD(mx, x) } + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +// Construct and append a CVTPS2PL instruction to the active function. +func (c *Context) CVTPS2PL(mx, x operand.Op) { + if inst, err := x86.CVTPS2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +// Construct and append a CVTPS2PL instruction to the active function. +// Operates on the global context. +func CVTPS2PL(mx, x operand.Op) { ctx.CVTPS2PL(mx, x) } + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +// Construct and append a CVTSD2SL instruction to the active function. +func (c *Context) CVTSD2SL(mx, r operand.Op) { + if inst, err := x86.CVTSD2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +// Construct and append a CVTSD2SL instruction to the active function. +// Operates on the global context. +func CVTSD2SL(mx, r operand.Op) { ctx.CVTSD2SL(mx, r) } + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +// Construct and append a CVTSD2SS instruction to the active function. +func (c *Context) CVTSD2SS(mx, x operand.Op) { + if inst, err := x86.CVTSD2SS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +// Construct and append a CVTSD2SS instruction to the active function. +// Operates on the global context. +func CVTSD2SS(mx, x operand.Op) { ctx.CVTSD2SS(mx, x) } + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +// Construct and append a CVTSL2SD instruction to the active function. +func (c *Context) CVTSL2SD(mr, x operand.Op) { + if inst, err := x86.CVTSL2SD(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +// Construct and append a CVTSL2SD instruction to the active function. +// Operates on the global context. +func CVTSL2SD(mr, x operand.Op) { ctx.CVTSL2SD(mr, x) } + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +// Construct and append a CVTSL2SS instruction to the active function. +func (c *Context) CVTSL2SS(mr, x operand.Op) { + if inst, err := x86.CVTSL2SS(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +// Construct and append a CVTSL2SS instruction to the active function. +// Operates on the global context. +func CVTSL2SS(mr, x operand.Op) { ctx.CVTSL2SS(mr, x) } + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +// Construct and append a CVTSQ2SD instruction to the active function. +func (c *Context) CVTSQ2SD(mr, x operand.Op) { + if inst, err := x86.CVTSQ2SD(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +// Construct and append a CVTSQ2SD instruction to the active function. +// Operates on the global context. +func CVTSQ2SD(mr, x operand.Op) { ctx.CVTSQ2SD(mr, x) } + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +// Construct and append a CVTSQ2SS instruction to the active function. +func (c *Context) CVTSQ2SS(mr, x operand.Op) { + if inst, err := x86.CVTSQ2SS(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +// Construct and append a CVTSQ2SS instruction to the active function. +// Operates on the global context. +func CVTSQ2SS(mr, x operand.Op) { ctx.CVTSQ2SS(mr, x) } + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +// Construct and append a CVTSS2SD instruction to the active function. +func (c *Context) CVTSS2SD(mx, x operand.Op) { + if inst, err := x86.CVTSS2SD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +// Construct and append a CVTSS2SD instruction to the active function. +// Operates on the global context. +func CVTSS2SD(mx, x operand.Op) { ctx.CVTSS2SD(mx, x) } + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +// Construct and append a CVTSS2SL instruction to the active function. +func (c *Context) CVTSS2SL(mx, r operand.Op) { + if inst, err := x86.CVTSS2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +// Construct and append a CVTSS2SL instruction to the active function. +// Operates on the global context. +func CVTSS2SL(mx, r operand.Op) { ctx.CVTSS2SL(mx, r) } + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +// Construct and append a CVTTPD2PL instruction to the active function. +func (c *Context) CVTTPD2PL(mx, x operand.Op) { + if inst, err := x86.CVTTPD2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +// Construct and append a CVTTPD2PL instruction to the active function. +// Operates on the global context. +func CVTTPD2PL(mx, x operand.Op) { ctx.CVTTPD2PL(mx, x) } + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +// Construct and append a CVTTPS2PL instruction to the active function. +func (c *Context) CVTTPS2PL(mx, x operand.Op) { + if inst, err := x86.CVTTPS2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +// Construct and append a CVTTPS2PL instruction to the active function. +// Operates on the global context. +func CVTTPS2PL(mx, x operand.Op) { ctx.CVTTPS2PL(mx, x) } + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +// Construct and append a CVTTSD2SL instruction to the active function. +func (c *Context) CVTTSD2SL(mx, r operand.Op) { + if inst, err := x86.CVTTSD2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +// Construct and append a CVTTSD2SL instruction to the active function. +// Operates on the global context. +func CVTTSD2SL(mx, r operand.Op) { ctx.CVTTSD2SL(mx, r) } + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +// Construct and append a CVTTSD2SQ instruction to the active function. +func (c *Context) CVTTSD2SQ(mx, r operand.Op) { + if inst, err := x86.CVTTSD2SQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +// Construct and append a CVTTSD2SQ instruction to the active function. +// Operates on the global context. +func CVTTSD2SQ(mx, r operand.Op) { ctx.CVTTSD2SQ(mx, r) } + +// 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 +// Construct and append a CVTTSS2SL instruction to the active function. +func (c *Context) CVTTSS2SL(mx, r operand.Op) { + if inst, err := x86.CVTTSS2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a CVTTSS2SL instruction to the active function. +// Operates on the global context. +func CVTTSS2SL(mx, r operand.Op) { ctx.CVTTSS2SL(mx, r) } + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +// Construct and append a CWD instruction to the active function. +func (c *Context) CWD() { + if inst, err := x86.CWD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +// Construct and append a CWD instruction to the active function. +// Operates on the global context. +func CWD() { ctx.CWD() } + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +// Construct and append a CWDE instruction to the active function. +func (c *Context) CWDE() { + if inst, err := x86.CWDE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +// Construct and append a CWDE instruction to the active function. +// Operates on the global context. +func CWDE() { ctx.CWDE() } + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +// Construct and append a DECB instruction to the active function. +func (c *Context) DECB(mr operand.Op) { + if inst, err := x86.DECB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +// Construct and append a DECB instruction to the active function. +// Operates on the global context. +func DECB(mr operand.Op) { ctx.DECB(mr) } + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +// Construct and append a DECL instruction to the active function. +func (c *Context) DECL(mr operand.Op) { + if inst, err := x86.DECL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +// Construct and append a DECL instruction to the active function. +// Operates on the global context. +func DECL(mr operand.Op) { ctx.DECL(mr) } + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +// Construct and append a DECQ instruction to the active function. +func (c *Context) DECQ(mr operand.Op) { + if inst, err := x86.DECQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +// Construct and append a DECQ instruction to the active function. +// Operates on the global context. +func DECQ(mr operand.Op) { ctx.DECQ(mr) } + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +// Construct and append a DECW instruction to the active function. +func (c *Context) DECW(mr operand.Op) { + if inst, err := x86.DECW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +// Construct and append a DECW instruction to the active function. +// Operates on the global context. +func DECW(mr operand.Op) { ctx.DECW(mr) } + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +// Construct and append a DIVB instruction to the active function. +func (c *Context) DIVB(mr operand.Op) { + if inst, err := x86.DIVB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +// Construct and append a DIVB instruction to the active function. +// Operates on the global context. +func DIVB(mr operand.Op) { ctx.DIVB(mr) } + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +// Construct and append a DIVL instruction to the active function. +func (c *Context) DIVL(mr operand.Op) { + if inst, err := x86.DIVL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +// Construct and append a DIVL instruction to the active function. +// Operates on the global context. +func DIVL(mr operand.Op) { ctx.DIVL(mr) } + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +// Construct and append a DIVPD instruction to the active function. +func (c *Context) DIVPD(mx, x operand.Op) { + if inst, err := x86.DIVPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +// Construct and append a DIVPD instruction to the active function. +// Operates on the global context. +func DIVPD(mx, x operand.Op) { ctx.DIVPD(mx, x) } + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +// Construct and append a DIVPS instruction to the active function. +func (c *Context) DIVPS(mx, x operand.Op) { + if inst, err := x86.DIVPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +// Construct and append a DIVPS instruction to the active function. +// Operates on the global context. +func DIVPS(mx, x operand.Op) { ctx.DIVPS(mx, x) } + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +// Construct and append a DIVQ instruction to the active function. +func (c *Context) DIVQ(mr operand.Op) { + if inst, err := x86.DIVQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +// Construct and append a DIVQ instruction to the active function. +// Operates on the global context. +func DIVQ(mr operand.Op) { ctx.DIVQ(mr) } + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +// Construct and append a DIVSD instruction to the active function. +func (c *Context) DIVSD(mx, x operand.Op) { + if inst, err := x86.DIVSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +// Construct and append a DIVSD instruction to the active function. +// Operates on the global context. +func DIVSD(mx, x operand.Op) { ctx.DIVSD(mx, x) } + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +// Construct and append a DIVSS instruction to the active function. +func (c *Context) DIVSS(mx, x operand.Op) { + if inst, err := x86.DIVSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +// Construct and append a DIVSS instruction to the active function. +// Operates on the global context. +func DIVSS(mx, x operand.Op) { ctx.DIVSS(mx, x) } + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +// Construct and append a DIVW instruction to the active function. +func (c *Context) DIVW(mr operand.Op) { + if inst, err := x86.DIVW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +// Construct and append a DIVW instruction to the active function. +// Operates on the global context. +func DIVW(mr operand.Op) { ctx.DIVW(mr) } + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +// Construct and append a DPPD instruction to the active function. +func (c *Context) DPPD(i, mx, x operand.Op) { + if inst, err := x86.DPPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +// Construct and append a DPPD instruction to the active function. +// Operates on the global context. +func DPPD(i, mx, x operand.Op) { ctx.DPPD(i, mx, x) } + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +// Construct and append a DPPS instruction to the active function. +func (c *Context) DPPS(i, mx, x operand.Op) { + if inst, err := x86.DPPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +// Construct and append a DPPS instruction to the active function. +// Operates on the global context. +func DPPS(i, mx, x operand.Op) { ctx.DPPS(i, mx, x) } + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +// Construct and append a EXTRACTPS instruction to the active function. +func (c *Context) EXTRACTPS(i, x, mr operand.Op) { + if inst, err := x86.EXTRACTPS(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +// Construct and append a EXTRACTPS instruction to the active function. +// Operates on the global context. +func EXTRACTPS(i, x, mr operand.Op) { ctx.EXTRACTPS(i, x, mr) } + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +// Construct and append a HADDPD instruction to the active function. +func (c *Context) HADDPD(mx, x operand.Op) { + if inst, err := x86.HADDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +// Construct and append a HADDPD instruction to the active function. +// Operates on the global context. +func HADDPD(mx, x operand.Op) { ctx.HADDPD(mx, x) } + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +// Construct and append a HADDPS instruction to the active function. +func (c *Context) HADDPS(mx, x operand.Op) { + if inst, err := x86.HADDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +// Construct and append a HADDPS instruction to the active function. +// Operates on the global context. +func HADDPS(mx, x operand.Op) { ctx.HADDPS(mx, x) } + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +// Construct and append a HSUBPD instruction to the active function. +func (c *Context) HSUBPD(mx, x operand.Op) { + if inst, err := x86.HSUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +// Construct and append a HSUBPD instruction to the active function. +// Operates on the global context. +func HSUBPD(mx, x operand.Op) { ctx.HSUBPD(mx, x) } + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +// Construct and append a HSUBPS instruction to the active function. +func (c *Context) HSUBPS(mx, x operand.Op) { + if inst, err := x86.HSUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +// Construct and append a HSUBPS instruction to the active function. +// Operates on the global context. +func HSUBPS(mx, x operand.Op) { ctx.HSUBPS(mx, x) } + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +// Construct and append a IDIVB instruction to the active function. +func (c *Context) IDIVB(mr operand.Op) { + if inst, err := x86.IDIVB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +// Construct and append a IDIVB instruction to the active function. +// Operates on the global context. +func IDIVB(mr operand.Op) { ctx.IDIVB(mr) } + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +// Construct and append a IDIVL instruction to the active function. +func (c *Context) IDIVL(mr operand.Op) { + if inst, err := x86.IDIVL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +// Construct and append a IDIVL instruction to the active function. +// Operates on the global context. +func IDIVL(mr operand.Op) { ctx.IDIVL(mr) } + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +// Construct and append a IDIVQ instruction to the active function. +func (c *Context) IDIVQ(mr operand.Op) { + if inst, err := x86.IDIVQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +// Construct and append a IDIVQ instruction to the active function. +// Operates on the global context. +func IDIVQ(mr operand.Op) { ctx.IDIVQ(mr) } + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +// Construct and append a IDIVW instruction to the active function. +func (c *Context) IDIVW(mr operand.Op) { + if inst, err := x86.IDIVW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +// Construct and append a IDIVW instruction to the active function. +// Operates on the global context. +func IDIVW(mr operand.Op) { ctx.IDIVW(mr) } + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +// Construct and append a IMUL3L instruction to the active function. +func (c *Context) IMUL3L(i, mr, r operand.Op) { + if inst, err := x86.IMUL3L(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +// Construct and append a IMUL3L instruction to the active function. +// Operates on the global context. +func IMUL3L(i, mr, r operand.Op) { ctx.IMUL3L(i, mr, r) } + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +// Construct and append a IMUL3Q instruction to the active function. +func (c *Context) IMUL3Q(i, mr, r operand.Op) { + if inst, err := x86.IMUL3Q(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +// Construct and append a IMUL3Q instruction to the active function. +// Operates on the global context. +func IMUL3Q(i, mr, r operand.Op) { ctx.IMUL3Q(i, mr, r) } + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +// Construct and append a IMUL3W instruction to the active function. +func (c *Context) IMUL3W(i, mr, r operand.Op) { + if inst, err := x86.IMUL3W(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +// Construct and append a IMUL3W instruction to the active function. +// Operates on the global context. +func IMUL3W(i, mr, r operand.Op) { ctx.IMUL3W(i, mr, r) } + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +// Construct and append a IMULB instruction to the active function. +func (c *Context) IMULB(mr operand.Op) { + if inst, err := x86.IMULB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +// Construct and append a IMULB instruction to the active function. +// Operates on the global context. +func IMULB(mr operand.Op) { ctx.IMULB(mr) } + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +// Construct and append a IMULL instruction to the active function. +func (c *Context) IMULL(ops ...operand.Op) { + if inst, err := x86.IMULL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +// Construct and append a IMULL instruction to the active function. +// Operates on the global context. +func IMULL(ops ...operand.Op) { ctx.IMULL(ops...) } + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +// Construct and append a IMULQ instruction to the active function. +func (c *Context) IMULQ(ops ...operand.Op) { + if inst, err := x86.IMULQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +// Construct and append a IMULQ instruction to the active function. +// Operates on the global context. +func IMULQ(ops ...operand.Op) { ctx.IMULQ(ops...) } + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +// Construct and append a IMULW instruction to the active function. +func (c *Context) IMULW(ops ...operand.Op) { + if inst, err := x86.IMULW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +// Construct and append a IMULW instruction to the active function. +// Operates on the global context. +func IMULW(ops ...operand.Op) { ctx.IMULW(ops...) } + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +// Construct and append a INCB instruction to the active function. +func (c *Context) INCB(mr operand.Op) { + if inst, err := x86.INCB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +// Construct and append a INCB instruction to the active function. +// Operates on the global context. +func INCB(mr operand.Op) { ctx.INCB(mr) } + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +// Construct and append a INCL instruction to the active function. +func (c *Context) INCL(mr operand.Op) { + if inst, err := x86.INCL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +// Construct and append a INCL instruction to the active function. +// Operates on the global context. +func INCL(mr operand.Op) { ctx.INCL(mr) } + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +// Construct and append a INCQ instruction to the active function. +func (c *Context) INCQ(mr operand.Op) { + if inst, err := x86.INCQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +// Construct and append a INCQ instruction to the active function. +// Operates on the global context. +func INCQ(mr operand.Op) { ctx.INCQ(mr) } + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +// Construct and append a INCW instruction to the active function. +func (c *Context) INCW(mr operand.Op) { + if inst, err := x86.INCW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +// Construct and append a INCW instruction to the active function. +// Operates on the global context. +func INCW(mr operand.Op) { ctx.INCW(mr) } + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +// Construct and append a INSERTPS instruction to the active function. +func (c *Context) INSERTPS(i, mx, x operand.Op) { + if inst, err := x86.INSERTPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +// Construct and append a INSERTPS instruction to the active function. +// Operates on the global context. +func INSERTPS(i, mx, x operand.Op) { ctx.INSERTPS(i, mx, x) } + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +// Construct and append a INT instruction to the active function. +func (c *Context) INT(i operand.Op) { + if inst, err := x86.INT(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +// Construct and append a INT instruction to the active function. +// Operates on the global context. +func INT(i operand.Op) { ctx.INT(i) } + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +// Construct and append a JA instruction to the active function. +func (c *Context) JA(r operand.Op) { + if inst, err := x86.JA(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +// Construct and append a JA instruction to the active function. +// Operates on the global context. +func JA(r operand.Op) { ctx.JA(r) } + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +// Construct and append a JAE instruction to the active function. +func (c *Context) JAE(r operand.Op) { + if inst, err := x86.JAE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +// Construct and append a JAE instruction to the active function. +// Operates on the global context. +func JAE(r operand.Op) { ctx.JAE(r) } + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +// Construct and append a JB instruction to the active function. +func (c *Context) JB(r operand.Op) { + if inst, err := x86.JB(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +// Construct and append a JB instruction to the active function. +// Operates on the global context. +func JB(r operand.Op) { ctx.JB(r) } + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +// Construct and append a JBE instruction to the active function. +func (c *Context) JBE(r operand.Op) { + if inst, err := x86.JBE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +// Construct and append a JBE instruction to the active function. +// Operates on the global context. +func JBE(r operand.Op) { ctx.JBE(r) } + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +// Construct and append a JC instruction to the active function. +func (c *Context) JC(r operand.Op) { + if inst, err := x86.JC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +// Construct and append a JC instruction to the active function. +// Operates on the global context. +func JC(r operand.Op) { ctx.JC(r) } + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +// Construct and append a JCC instruction to the active function. +func (c *Context) JCC(r operand.Op) { + if inst, err := x86.JCC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +// Construct and append a JCC instruction to the active function. +// Operates on the global context. +func JCC(r operand.Op) { ctx.JCC(r) } + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +// Construct and append a JCS instruction to the active function. +func (c *Context) JCS(r operand.Op) { + if inst, err := x86.JCS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +// Construct and append a JCS instruction to the active function. +// Operates on the global context. +func JCS(r operand.Op) { ctx.JCS(r) } + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +// Construct and append a JCXZL instruction to the active function. +func (c *Context) JCXZL(r operand.Op) { + if inst, err := x86.JCXZL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +// Construct and append a JCXZL instruction to the active function. +// Operates on the global context. +func JCXZL(r operand.Op) { ctx.JCXZL(r) } + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +// Construct and append a JCXZQ instruction to the active function. +func (c *Context) JCXZQ(r operand.Op) { + if inst, err := x86.JCXZQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +// Construct and append a JCXZQ instruction to the active function. +// Operates on the global context. +func JCXZQ(r operand.Op) { ctx.JCXZQ(r) } + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +// Construct and append a JE instruction to the active function. +func (c *Context) JE(r operand.Op) { + if inst, err := x86.JE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +// Construct and append a JE instruction to the active function. +// Operates on the global context. +func JE(r operand.Op) { ctx.JE(r) } + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +// Construct and append a JEQ instruction to the active function. +func (c *Context) JEQ(r operand.Op) { + if inst, err := x86.JEQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +// Construct and append a JEQ instruction to the active function. +// Operates on the global context. +func JEQ(r operand.Op) { ctx.JEQ(r) } + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +// Construct and append a JG instruction to the active function. +func (c *Context) JG(r operand.Op) { + if inst, err := x86.JG(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +// Construct and append a JG instruction to the active function. +// Operates on the global context. +func JG(r operand.Op) { ctx.JG(r) } + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +// Construct and append a JGE instruction to the active function. +func (c *Context) JGE(r operand.Op) { + if inst, err := x86.JGE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +// Construct and append a JGE instruction to the active function. +// Operates on the global context. +func JGE(r operand.Op) { ctx.JGE(r) } + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +// Construct and append a JGT instruction to the active function. +func (c *Context) JGT(r operand.Op) { + if inst, err := x86.JGT(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +// Construct and append a JGT instruction to the active function. +// Operates on the global context. +func JGT(r operand.Op) { ctx.JGT(r) } + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +// Construct and append a JHI instruction to the active function. +func (c *Context) JHI(r operand.Op) { + if inst, err := x86.JHI(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +// Construct and append a JHI instruction to the active function. +// Operates on the global context. +func JHI(r operand.Op) { ctx.JHI(r) } + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +// Construct and append a JHS instruction to the active function. +func (c *Context) JHS(r operand.Op) { + if inst, err := x86.JHS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +// Construct and append a JHS instruction to the active function. +// Operates on the global context. +func JHS(r operand.Op) { ctx.JHS(r) } + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +// Construct and append a JL instruction to the active function. +func (c *Context) JL(r operand.Op) { + if inst, err := x86.JL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +// Construct and append a JL instruction to the active function. +// Operates on the global context. +func JL(r operand.Op) { ctx.JL(r) } + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +// Construct and append a JLE instruction to the active function. +func (c *Context) JLE(r operand.Op) { + if inst, err := x86.JLE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +// Construct and append a JLE instruction to the active function. +// Operates on the global context. +func JLE(r operand.Op) { ctx.JLE(r) } + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +// Construct and append a JLO instruction to the active function. +func (c *Context) JLO(r operand.Op) { + if inst, err := x86.JLO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +// Construct and append a JLO instruction to the active function. +// Operates on the global context. +func JLO(r operand.Op) { ctx.JLO(r) } + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +// Construct and append a JLS instruction to the active function. +func (c *Context) JLS(r operand.Op) { + if inst, err := x86.JLS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +// Construct and append a JLS instruction to the active function. +// Operates on the global context. +func JLS(r operand.Op) { ctx.JLS(r) } + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +// Construct and append a JLT instruction to the active function. +func (c *Context) JLT(r operand.Op) { + if inst, err := x86.JLT(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +// Construct and append a JLT instruction to the active function. +// Operates on the global context. +func JLT(r operand.Op) { ctx.JLT(r) } + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +// Construct and append a JMI instruction to the active function. +func (c *Context) JMI(r operand.Op) { + if inst, err := x86.JMI(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +// Construct and append a JMI instruction to the active function. +// Operates on the global context. +func JMI(r operand.Op) { ctx.JMI(r) } + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +// Construct and append a JMP instruction to the active function. +func (c *Context) JMP(mr operand.Op) { + if inst, err := x86.JMP(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +// Construct and append a JMP instruction to the active function. +// Operates on the global context. +func JMP(mr operand.Op) { ctx.JMP(mr) } + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +// Construct and append a JNA instruction to the active function. +func (c *Context) JNA(r operand.Op) { + if inst, err := x86.JNA(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +// Construct and append a JNA instruction to the active function. +// Operates on the global context. +func JNA(r operand.Op) { ctx.JNA(r) } + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +// Construct and append a JNAE instruction to the active function. +func (c *Context) JNAE(r operand.Op) { + if inst, err := x86.JNAE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +// Construct and append a JNAE instruction to the active function. +// Operates on the global context. +func JNAE(r operand.Op) { ctx.JNAE(r) } + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +// Construct and append a JNB instruction to the active function. +func (c *Context) JNB(r operand.Op) { + if inst, err := x86.JNB(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +// Construct and append a JNB instruction to the active function. +// Operates on the global context. +func JNB(r operand.Op) { ctx.JNB(r) } + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +// Construct and append a JNBE instruction to the active function. +func (c *Context) JNBE(r operand.Op) { + if inst, err := x86.JNBE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +// Construct and append a JNBE instruction to the active function. +// Operates on the global context. +func JNBE(r operand.Op) { ctx.JNBE(r) } + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +// Construct and append a JNC instruction to the active function. +func (c *Context) JNC(r operand.Op) { + if inst, err := x86.JNC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +// Construct and append a JNC instruction to the active function. +// Operates on the global context. +func JNC(r operand.Op) { ctx.JNC(r) } + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +// Construct and append a JNE instruction to the active function. +func (c *Context) JNE(r operand.Op) { + if inst, err := x86.JNE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +// Construct and append a JNE instruction to the active function. +// Operates on the global context. +func JNE(r operand.Op) { ctx.JNE(r) } + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +// Construct and append a JNG instruction to the active function. +func (c *Context) JNG(r operand.Op) { + if inst, err := x86.JNG(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +// Construct and append a JNG instruction to the active function. +// Operates on the global context. +func JNG(r operand.Op) { ctx.JNG(r) } + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +// Construct and append a JNGE instruction to the active function. +func (c *Context) JNGE(r operand.Op) { + if inst, err := x86.JNGE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +// Construct and append a JNGE instruction to the active function. +// Operates on the global context. +func JNGE(r operand.Op) { ctx.JNGE(r) } + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +// Construct and append a JNL instruction to the active function. +func (c *Context) JNL(r operand.Op) { + if inst, err := x86.JNL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +// Construct and append a JNL instruction to the active function. +// Operates on the global context. +func JNL(r operand.Op) { ctx.JNL(r) } + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +// Construct and append a JNLE instruction to the active function. +func (c *Context) JNLE(r operand.Op) { + if inst, err := x86.JNLE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +// Construct and append a JNLE instruction to the active function. +// Operates on the global context. +func JNLE(r operand.Op) { ctx.JNLE(r) } + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +// Construct and append a JNO instruction to the active function. +func (c *Context) JNO(r operand.Op) { + if inst, err := x86.JNO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +// Construct and append a JNO instruction to the active function. +// Operates on the global context. +func JNO(r operand.Op) { ctx.JNO(r) } + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +// Construct and append a JNP instruction to the active function. +func (c *Context) JNP(r operand.Op) { + if inst, err := x86.JNP(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +// Construct and append a JNP instruction to the active function. +// Operates on the global context. +func JNP(r operand.Op) { ctx.JNP(r) } + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +// Construct and append a JNS instruction to the active function. +func (c *Context) JNS(r operand.Op) { + if inst, err := x86.JNS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +// Construct and append a JNS instruction to the active function. +// Operates on the global context. +func JNS(r operand.Op) { ctx.JNS(r) } + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +// Construct and append a JNZ instruction to the active function. +func (c *Context) JNZ(r operand.Op) { + if inst, err := x86.JNZ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +// Construct and append a JNZ instruction to the active function. +// Operates on the global context. +func JNZ(r operand.Op) { ctx.JNZ(r) } + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +// Construct and append a JO instruction to the active function. +func (c *Context) JO(r operand.Op) { + if inst, err := x86.JO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +// Construct and append a JO instruction to the active function. +// Operates on the global context. +func JO(r operand.Op) { ctx.JO(r) } + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +// Construct and append a JOC instruction to the active function. +func (c *Context) JOC(r operand.Op) { + if inst, err := x86.JOC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +// Construct and append a JOC instruction to the active function. +// Operates on the global context. +func JOC(r operand.Op) { ctx.JOC(r) } + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +// Construct and append a JOS instruction to the active function. +func (c *Context) JOS(r operand.Op) { + if inst, err := x86.JOS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +// Construct and append a JOS instruction to the active function. +// Operates on the global context. +func JOS(r operand.Op) { ctx.JOS(r) } + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +// Construct and append a JP instruction to the active function. +func (c *Context) JP(r operand.Op) { + if inst, err := x86.JP(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +// Construct and append a JP instruction to the active function. +// Operates on the global context. +func JP(r operand.Op) { ctx.JP(r) } + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +// Construct and append a JPC instruction to the active function. +func (c *Context) JPC(r operand.Op) { + if inst, err := x86.JPC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +// Construct and append a JPC instruction to the active function. +// Operates on the global context. +func JPC(r operand.Op) { ctx.JPC(r) } + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +// Construct and append a JPE instruction to the active function. +func (c *Context) JPE(r operand.Op) { + if inst, err := x86.JPE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +// Construct and append a JPE instruction to the active function. +// Operates on the global context. +func JPE(r operand.Op) { ctx.JPE(r) } + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +// Construct and append a JPL instruction to the active function. +func (c *Context) JPL(r operand.Op) { + if inst, err := x86.JPL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +// Construct and append a JPL instruction to the active function. +// Operates on the global context. +func JPL(r operand.Op) { ctx.JPL(r) } + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +// Construct and append a JPO instruction to the active function. +func (c *Context) JPO(r operand.Op) { + if inst, err := x86.JPO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +// Construct and append a JPO instruction to the active function. +// Operates on the global context. +func JPO(r operand.Op) { ctx.JPO(r) } + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +// Construct and append a JPS instruction to the active function. +func (c *Context) JPS(r operand.Op) { + if inst, err := x86.JPS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +// Construct and append a JPS instruction to the active function. +// Operates on the global context. +func JPS(r operand.Op) { ctx.JPS(r) } + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +// Construct and append a JS instruction to the active function. +func (c *Context) JS(r operand.Op) { + if inst, err := x86.JS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +// Construct and append a JS instruction to the active function. +// Operates on the global context. +func JS(r operand.Op) { ctx.JS(r) } + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +// Construct and append a JZ instruction to the active function. +func (c *Context) JZ(r operand.Op) { + if inst, err := x86.JZ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +// Construct and append a JZ instruction to the active function. +// Operates on the global context. +func JZ(r operand.Op) { ctx.JZ(r) } + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +// Construct and append a LDDQU instruction to the active function. +func (c *Context) LDDQU(m, x operand.Op) { + if inst, err := x86.LDDQU(m, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +// Construct and append a LDDQU instruction to the active function. +// Operates on the global context. +func LDDQU(m, x operand.Op) { ctx.LDDQU(m, x) } + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +// Construct and append a LDMXCSR instruction to the active function. +func (c *Context) LDMXCSR(m operand.Op) { + if inst, err := x86.LDMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +// Construct and append a LDMXCSR instruction to the active function. +// Operates on the global context. +func LDMXCSR(m operand.Op) { ctx.LDMXCSR(m) } + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +// Construct and append a LEAL instruction to the active function. +func (c *Context) LEAL(m, r operand.Op) { + if inst, err := x86.LEAL(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +// Construct and append a LEAL instruction to the active function. +// Operates on the global context. +func LEAL(m, r operand.Op) { ctx.LEAL(m, r) } + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +// Construct and append a LEAQ instruction to the active function. +func (c *Context) LEAQ(m, r operand.Op) { + if inst, err := x86.LEAQ(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +// Construct and append a LEAQ instruction to the active function. +// Operates on the global context. +func LEAQ(m, r operand.Op) { ctx.LEAQ(m, r) } + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +// Construct and append a LEAW instruction to the active function. +func (c *Context) LEAW(m, r operand.Op) { + if inst, err := x86.LEAW(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +// Construct and append a LEAW instruction to the active function. +// Operates on the global context. +func LEAW(m, r operand.Op) { ctx.LEAW(m, r) } + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +// Construct and append a LFENCE instruction to the active function. +func (c *Context) LFENCE() { + if inst, err := x86.LFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +// Construct and append a LFENCE instruction to the active function. +// Operates on the global context. +func LFENCE() { ctx.LFENCE() } + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +// Construct and append a LZCNTL instruction to the active function. +func (c *Context) LZCNTL(mr, r operand.Op) { + if inst, err := x86.LZCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +// Construct and append a LZCNTL instruction to the active function. +// Operates on the global context. +func LZCNTL(mr, r operand.Op) { ctx.LZCNTL(mr, r) } + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +// Construct and append a LZCNTQ instruction to the active function. +func (c *Context) LZCNTQ(mr, r operand.Op) { + if inst, err := x86.LZCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +// Construct and append a LZCNTQ instruction to the active function. +// Operates on the global context. +func LZCNTQ(mr, r operand.Op) { ctx.LZCNTQ(mr, r) } + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +// Construct and append a LZCNTW instruction to the active function. +func (c *Context) LZCNTW(mr, r operand.Op) { + if inst, err := x86.LZCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +// Construct and append a LZCNTW instruction to the active function. +// Operates on the global context. +func LZCNTW(mr, r operand.Op) { ctx.LZCNTW(mr, r) } + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +// Construct and append a MASKMOVDQU instruction to the active function. +func (c *Context) MASKMOVDQU(x, x1 operand.Op) { + if inst, err := x86.MASKMOVDQU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +// Construct and append a MASKMOVDQU instruction to the active function. +// Operates on the global context. +func MASKMOVDQU(x, x1 operand.Op) { ctx.MASKMOVDQU(x, x1) } + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +// Construct and append a MASKMOVOU instruction to the active function. +func (c *Context) MASKMOVOU(x, x1 operand.Op) { + if inst, err := x86.MASKMOVOU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +// Construct and append a MASKMOVOU instruction to the active function. +// Operates on the global context. +func MASKMOVOU(x, x1 operand.Op) { ctx.MASKMOVOU(x, x1) } + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +// Construct and append a MAXPD instruction to the active function. +func (c *Context) MAXPD(mx, x operand.Op) { + if inst, err := x86.MAXPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +// Construct and append a MAXPD instruction to the active function. +// Operates on the global context. +func MAXPD(mx, x operand.Op) { ctx.MAXPD(mx, x) } + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +// Construct and append a MAXPS instruction to the active function. +func (c *Context) MAXPS(mx, x operand.Op) { + if inst, err := x86.MAXPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +// Construct and append a MAXPS instruction to the active function. +// Operates on the global context. +func MAXPS(mx, x operand.Op) { ctx.MAXPS(mx, x) } + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +// Construct and append a MAXSD instruction to the active function. +func (c *Context) MAXSD(mx, x operand.Op) { + if inst, err := x86.MAXSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +// Construct and append a MAXSD instruction to the active function. +// Operates on the global context. +func MAXSD(mx, x operand.Op) { ctx.MAXSD(mx, x) } + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +// Construct and append a MAXSS instruction to the active function. +func (c *Context) MAXSS(mx, x operand.Op) { + if inst, err := x86.MAXSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +// Construct and append a MAXSS instruction to the active function. +// Operates on the global context. +func MAXSS(mx, x operand.Op) { ctx.MAXSS(mx, x) } + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +// Construct and append a MFENCE instruction to the active function. +func (c *Context) MFENCE() { + if inst, err := x86.MFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +// Construct and append a MFENCE instruction to the active function. +// Operates on the global context. +func MFENCE() { ctx.MFENCE() } + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +// Construct and append a MINPD instruction to the active function. +func (c *Context) MINPD(mx, x operand.Op) { + if inst, err := x86.MINPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +// Construct and append a MINPD instruction to the active function. +// Operates on the global context. +func MINPD(mx, x operand.Op) { ctx.MINPD(mx, x) } + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +// Construct and append a MINPS instruction to the active function. +func (c *Context) MINPS(mx, x operand.Op) { + if inst, err := x86.MINPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +// Construct and append a MINPS instruction to the active function. +// Operates on the global context. +func MINPS(mx, x operand.Op) { ctx.MINPS(mx, x) } + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +// Construct and append a MINSD instruction to the active function. +func (c *Context) MINSD(mx, x operand.Op) { + if inst, err := x86.MINSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +// Construct and append a MINSD instruction to the active function. +// Operates on the global context. +func MINSD(mx, x operand.Op) { ctx.MINSD(mx, x) } + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +// Construct and append a MINSS instruction to the active function. +func (c *Context) MINSS(mx, x operand.Op) { + if inst, err := x86.MINSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +// Construct and append a MINSS instruction to the active function. +// Operates on the global context. +func MINSS(mx, x operand.Op) { ctx.MINSS(mx, x) } + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +// Construct and append a MONITOR instruction to the active function. +func (c *Context) MONITOR() { + if inst, err := x86.MONITOR(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +// Construct and append a MONITOR instruction to the active function. +// Operates on the global context. +func MONITOR() { ctx.MONITOR() } + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +// Construct and append a MOVAPD instruction to the active function. +func (c *Context) MOVAPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVAPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +// Construct and append a MOVAPD instruction to the active function. +// Operates on the global context. +func MOVAPD(mx, mx1 operand.Op) { ctx.MOVAPD(mx, mx1) } + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +// Construct and append a MOVAPS instruction to the active function. +func (c *Context) MOVAPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVAPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +// Construct and append a MOVAPS instruction to the active function. +// Operates on the global context. +func MOVAPS(mx, mx1 operand.Op) { ctx.MOVAPS(mx, mx1) } + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +// Construct and append a MOVB instruction to the active function. +func (c *Context) MOVB(imr, mr operand.Op) { + if inst, err := x86.MOVB(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +// Construct and append a MOVB instruction to the active function. +// Operates on the global context. +func MOVB(imr, mr operand.Op) { ctx.MOVB(imr, mr) } + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +// Construct and append a MOVBELL instruction to the active function. +func (c *Context) MOVBELL(mr, mr1 operand.Op) { + if inst, err := x86.MOVBELL(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +// Construct and append a MOVBELL instruction to the active function. +// Operates on the global context. +func MOVBELL(mr, mr1 operand.Op) { ctx.MOVBELL(mr, mr1) } + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +// Construct and append a MOVBEQQ instruction to the active function. +func (c *Context) MOVBEQQ(mr, mr1 operand.Op) { + if inst, err := x86.MOVBEQQ(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +// Construct and append a MOVBEQQ instruction to the active function. +// Operates on the global context. +func MOVBEQQ(mr, mr1 operand.Op) { ctx.MOVBEQQ(mr, mr1) } + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +// Construct and append a MOVBEWW instruction to the active function. +func (c *Context) MOVBEWW(mr, mr1 operand.Op) { + if inst, err := x86.MOVBEWW(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +// Construct and append a MOVBEWW instruction to the active function. +// Operates on the global context. +func MOVBEWW(mr, mr1 operand.Op) { ctx.MOVBEWW(mr, mr1) } + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +// Construct and append a MOVBLSX instruction to the active function. +func (c *Context) MOVBLSX(mr, r operand.Op) { + if inst, err := x86.MOVBLSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +// Construct and append a MOVBLSX instruction to the active function. +// Operates on the global context. +func MOVBLSX(mr, r operand.Op) { ctx.MOVBLSX(mr, r) } + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +// Construct and append a MOVBLZX instruction to the active function. +func (c *Context) MOVBLZX(mr, r operand.Op) { + if inst, err := x86.MOVBLZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +// Construct and append a MOVBLZX instruction to the active function. +// Operates on the global context. +func MOVBLZX(mr, r operand.Op) { ctx.MOVBLZX(mr, r) } + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +// Construct and append a MOVBQSX instruction to the active function. +func (c *Context) MOVBQSX(mr, r operand.Op) { + if inst, err := x86.MOVBQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +// Construct and append a MOVBQSX instruction to the active function. +// Operates on the global context. +func MOVBQSX(mr, r operand.Op) { ctx.MOVBQSX(mr, r) } + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +// Construct and append a MOVBQZX instruction to the active function. +func (c *Context) MOVBQZX(mr, r operand.Op) { + if inst, err := x86.MOVBQZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +// Construct and append a MOVBQZX instruction to the active function. +// Operates on the global context. +func MOVBQZX(mr, r operand.Op) { ctx.MOVBQZX(mr, r) } + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +// Construct and append a MOVBWSX instruction to the active function. +func (c *Context) MOVBWSX(mr, r operand.Op) { + if inst, err := x86.MOVBWSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +// Construct and append a MOVBWSX instruction to the active function. +// Operates on the global context. +func MOVBWSX(mr, r operand.Op) { ctx.MOVBWSX(mr, r) } + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +// Construct and append a MOVBWZX instruction to the active function. +func (c *Context) MOVBWZX(mr, r operand.Op) { + if inst, err := x86.MOVBWZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +// Construct and append a MOVBWZX instruction to the active function. +// Operates on the global context. +func MOVBWZX(mr, r operand.Op) { ctx.MOVBWZX(mr, r) } + +// 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 +// Construct and append a MOVD instruction to the active function. +func (c *Context) MOVD(imrx, mrx operand.Op) { + if inst, err := x86.MOVD(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a MOVD instruction to the active function. +// Operates on the global context. +func MOVD(imrx, mrx operand.Op) { ctx.MOVD(imrx, mrx) } + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +// Construct and append a MOVDDUP instruction to the active function. +func (c *Context) MOVDDUP(mx, x operand.Op) { + if inst, err := x86.MOVDDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +// Construct and append a MOVDDUP instruction to the active function. +// Operates on the global context. +func MOVDDUP(mx, x operand.Op) { ctx.MOVDDUP(mx, x) } + +// 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 +// Construct and append a MOVDQ2Q instruction to the active function. +func (c *Context) MOVDQ2Q(imrx, mrx operand.Op) { + if inst, err := x86.MOVDQ2Q(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a MOVDQ2Q instruction to the active function. +// Operates on the global context. +func MOVDQ2Q(imrx, mrx operand.Op) { ctx.MOVDQ2Q(imrx, mrx) } + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +// Construct and append a MOVHLPS instruction to the active function. +func (c *Context) MOVHLPS(x, x1 operand.Op) { + if inst, err := x86.MOVHLPS(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +// Construct and append a MOVHLPS instruction to the active function. +// Operates on the global context. +func MOVHLPS(x, x1 operand.Op) { ctx.MOVHLPS(x, x1) } + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +// Construct and append a MOVHPD instruction to the active function. +func (c *Context) MOVHPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVHPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +// Construct and append a MOVHPD instruction to the active function. +// Operates on the global context. +func MOVHPD(mx, mx1 operand.Op) { ctx.MOVHPD(mx, mx1) } + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +// Construct and append a MOVHPS instruction to the active function. +func (c *Context) MOVHPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVHPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +// Construct and append a MOVHPS instruction to the active function. +// Operates on the global context. +func MOVHPS(mx, mx1 operand.Op) { ctx.MOVHPS(mx, mx1) } + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +// Construct and append a MOVL instruction to the active function. +func (c *Context) MOVL(imr, mr operand.Op) { + if inst, err := x86.MOVL(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +// Construct and append a MOVL instruction to the active function. +// Operates on the global context. +func MOVL(imr, mr operand.Op) { ctx.MOVL(imr, mr) } + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +// Construct and append a MOVLHPS instruction to the active function. +func (c *Context) MOVLHPS(x, x1 operand.Op) { + if inst, err := x86.MOVLHPS(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +// Construct and append a MOVLHPS instruction to the active function. +// Operates on the global context. +func MOVLHPS(x, x1 operand.Op) { ctx.MOVLHPS(x, x1) } + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +// Construct and append a MOVLPD instruction to the active function. +func (c *Context) MOVLPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVLPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +// Construct and append a MOVLPD instruction to the active function. +// Operates on the global context. +func MOVLPD(mx, mx1 operand.Op) { ctx.MOVLPD(mx, mx1) } + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +// Construct and append a MOVLPS instruction to the active function. +func (c *Context) MOVLPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVLPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +// Construct and append a MOVLPS instruction to the active function. +// Operates on the global context. +func MOVLPS(mx, mx1 operand.Op) { ctx.MOVLPS(mx, mx1) } + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +// Construct and append a MOVLQSX instruction to the active function. +func (c *Context) MOVLQSX(mr, r operand.Op) { + if inst, err := x86.MOVLQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +// Construct and append a MOVLQSX instruction to the active function. +// Operates on the global context. +func MOVLQSX(mr, r operand.Op) { ctx.MOVLQSX(mr, r) } + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +// Construct and append a MOVLQZX instruction to the active function. +func (c *Context) MOVLQZX(m, r operand.Op) { + if inst, err := x86.MOVLQZX(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +// Construct and append a MOVLQZX instruction to the active function. +// Operates on the global context. +func MOVLQZX(m, r operand.Op) { ctx.MOVLQZX(m, r) } + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +// Construct and append a MOVMSKPD instruction to the active function. +func (c *Context) MOVMSKPD(x, r operand.Op) { + if inst, err := x86.MOVMSKPD(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +// Construct and append a MOVMSKPD instruction to the active function. +// Operates on the global context. +func MOVMSKPD(x, r operand.Op) { ctx.MOVMSKPD(x, r) } + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +// Construct and append a MOVMSKPS instruction to the active function. +func (c *Context) MOVMSKPS(x, r operand.Op) { + if inst, err := x86.MOVMSKPS(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +// Construct and append a MOVMSKPS instruction to the active function. +// Operates on the global context. +func MOVMSKPS(x, r operand.Op) { ctx.MOVMSKPS(x, r) } + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +// Construct and append a MOVNTDQ instruction to the active function. +func (c *Context) MOVNTDQ(x, m operand.Op) { + if inst, err := x86.MOVNTDQ(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +// Construct and append a MOVNTDQ instruction to the active function. +// Operates on the global context. +func MOVNTDQ(x, m operand.Op) { ctx.MOVNTDQ(x, m) } + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +// Construct and append a MOVNTDQA instruction to the active function. +func (c *Context) MOVNTDQA(m, x operand.Op) { + if inst, err := x86.MOVNTDQA(m, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +// Construct and append a MOVNTDQA instruction to the active function. +// Operates on the global context. +func MOVNTDQA(m, x operand.Op) { ctx.MOVNTDQA(m, x) } + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +// Construct and append a MOVNTIL instruction to the active function. +func (c *Context) MOVNTIL(r, m operand.Op) { + if inst, err := x86.MOVNTIL(r, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +// Construct and append a MOVNTIL instruction to the active function. +// Operates on the global context. +func MOVNTIL(r, m operand.Op) { ctx.MOVNTIL(r, m) } + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +// Construct and append a MOVNTIQ instruction to the active function. +func (c *Context) MOVNTIQ(r, m operand.Op) { + if inst, err := x86.MOVNTIQ(r, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +// Construct and append a MOVNTIQ instruction to the active function. +// Operates on the global context. +func MOVNTIQ(r, m operand.Op) { ctx.MOVNTIQ(r, m) } + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +// Construct and append a MOVNTO instruction to the active function. +func (c *Context) MOVNTO(x, m operand.Op) { + if inst, err := x86.MOVNTO(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +// Construct and append a MOVNTO instruction to the active function. +// Operates on the global context. +func MOVNTO(x, m operand.Op) { ctx.MOVNTO(x, m) } + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +// Construct and append a MOVNTPD instruction to the active function. +func (c *Context) MOVNTPD(x, m operand.Op) { + if inst, err := x86.MOVNTPD(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +// Construct and append a MOVNTPD instruction to the active function. +// Operates on the global context. +func MOVNTPD(x, m operand.Op) { ctx.MOVNTPD(x, m) } + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +// Construct and append a MOVNTPS instruction to the active function. +func (c *Context) MOVNTPS(x, m operand.Op) { + if inst, err := x86.MOVNTPS(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +// Construct and append a MOVNTPS instruction to the active function. +// Operates on the global context. +func MOVNTPS(x, m operand.Op) { ctx.MOVNTPS(x, m) } + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +// Construct and append a MOVO instruction to the active function. +func (c *Context) MOVO(mx, mx1 operand.Op) { + if inst, err := x86.MOVO(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +// Construct and append a MOVO instruction to the active function. +// Operates on the global context. +func MOVO(mx, mx1 operand.Op) { ctx.MOVO(mx, mx1) } + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +// Construct and append a MOVOA instruction to the active function. +func (c *Context) MOVOA(mx, mx1 operand.Op) { + if inst, err := x86.MOVOA(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +// Construct and append a MOVOA instruction to the active function. +// Operates on the global context. +func MOVOA(mx, mx1 operand.Op) { ctx.MOVOA(mx, mx1) } + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +// Construct and append a MOVOU instruction to the active function. +func (c *Context) MOVOU(mx, mx1 operand.Op) { + if inst, err := x86.MOVOU(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +// Construct and append a MOVOU instruction to the active function. +// Operates on the global context. +func MOVOU(mx, mx1 operand.Op) { ctx.MOVOU(mx, mx1) } + +// 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 +// Construct and append a MOVQ instruction to the active function. +func (c *Context) MOVQ(imrx, mrx operand.Op) { + if inst, err := x86.MOVQ(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a MOVQ instruction to the active function. +// Operates on the global context. +func MOVQ(imrx, mrx operand.Op) { ctx.MOVQ(imrx, mrx) } + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +// Construct and append a MOVSD instruction to the active function. +func (c *Context) MOVSD(mx, mx1 operand.Op) { + if inst, err := x86.MOVSD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +// Construct and append a MOVSD instruction to the active function. +// Operates on the global context. +func MOVSD(mx, mx1 operand.Op) { ctx.MOVSD(mx, mx1) } + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +// Construct and append a MOVSHDUP instruction to the active function. +func (c *Context) MOVSHDUP(mx, x operand.Op) { + if inst, err := x86.MOVSHDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +// Construct and append a MOVSHDUP instruction to the active function. +// Operates on the global context. +func MOVSHDUP(mx, x operand.Op) { ctx.MOVSHDUP(mx, x) } + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +// Construct and append a MOVSLDUP instruction to the active function. +func (c *Context) MOVSLDUP(mx, x operand.Op) { + if inst, err := x86.MOVSLDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +// Construct and append a MOVSLDUP instruction to the active function. +// Operates on the global context. +func MOVSLDUP(mx, x operand.Op) { ctx.MOVSLDUP(mx, x) } + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +// Construct and append a MOVSS instruction to the active function. +func (c *Context) MOVSS(mx, mx1 operand.Op) { + if inst, err := x86.MOVSS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +// Construct and append a MOVSS instruction to the active function. +// Operates on the global context. +func MOVSS(mx, mx1 operand.Op) { ctx.MOVSS(mx, mx1) } + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +// Construct and append a MOVUPD instruction to the active function. +func (c *Context) MOVUPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVUPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +// Construct and append a MOVUPD instruction to the active function. +// Operates on the global context. +func MOVUPD(mx, mx1 operand.Op) { ctx.MOVUPD(mx, mx1) } + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +// Construct and append a MOVUPS instruction to the active function. +func (c *Context) MOVUPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVUPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +// Construct and append a MOVUPS instruction to the active function. +// Operates on the global context. +func MOVUPS(mx, mx1 operand.Op) { ctx.MOVUPS(mx, mx1) } + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +// Construct and append a MOVW instruction to the active function. +func (c *Context) MOVW(imr, mr operand.Op) { + if inst, err := x86.MOVW(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +// Construct and append a MOVW instruction to the active function. +// Operates on the global context. +func MOVW(imr, mr operand.Op) { ctx.MOVW(imr, mr) } + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +// Construct and append a MOVWLSX instruction to the active function. +func (c *Context) MOVWLSX(mr, r operand.Op) { + if inst, err := x86.MOVWLSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +// Construct and append a MOVWLSX instruction to the active function. +// Operates on the global context. +func MOVWLSX(mr, r operand.Op) { ctx.MOVWLSX(mr, r) } + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +// Construct and append a MOVWLZX instruction to the active function. +func (c *Context) MOVWLZX(mr, r operand.Op) { + if inst, err := x86.MOVWLZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +// Construct and append a MOVWLZX instruction to the active function. +// Operates on the global context. +func MOVWLZX(mr, r operand.Op) { ctx.MOVWLZX(mr, r) } + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +// Construct and append a MOVWQSX instruction to the active function. +func (c *Context) MOVWQSX(mr, r operand.Op) { + if inst, err := x86.MOVWQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +// Construct and append a MOVWQSX instruction to the active function. +// Operates on the global context. +func MOVWQSX(mr, r operand.Op) { ctx.MOVWQSX(mr, r) } + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +// Construct and append a MOVWQZX instruction to the active function. +func (c *Context) MOVWQZX(mr, r operand.Op) { + if inst, err := x86.MOVWQZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +// Construct and append a MOVWQZX instruction to the active function. +// Operates on the global context. +func MOVWQZX(mr, r operand.Op) { ctx.MOVWQZX(mr, r) } + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +// Construct and append a MPSADBW instruction to the active function. +func (c *Context) MPSADBW(i, mx, x operand.Op) { + if inst, err := x86.MPSADBW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +// Construct and append a MPSADBW instruction to the active function. +// Operates on the global context. +func MPSADBW(i, mx, x operand.Op) { ctx.MPSADBW(i, mx, x) } + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +// Construct and append a MULB instruction to the active function. +func (c *Context) MULB(mr operand.Op) { + if inst, err := x86.MULB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +// Construct and append a MULB instruction to the active function. +// Operates on the global context. +func MULB(mr operand.Op) { ctx.MULB(mr) } + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +// Construct and append a MULL instruction to the active function. +func (c *Context) MULL(mr operand.Op) { + if inst, err := x86.MULL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +// Construct and append a MULL instruction to the active function. +// Operates on the global context. +func MULL(mr operand.Op) { ctx.MULL(mr) } + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +// Construct and append a MULPD instruction to the active function. +func (c *Context) MULPD(mx, x operand.Op) { + if inst, err := x86.MULPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +// Construct and append a MULPD instruction to the active function. +// Operates on the global context. +func MULPD(mx, x operand.Op) { ctx.MULPD(mx, x) } + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +// Construct and append a MULPS instruction to the active function. +func (c *Context) MULPS(mx, x operand.Op) { + if inst, err := x86.MULPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +// Construct and append a MULPS instruction to the active function. +// Operates on the global context. +func MULPS(mx, x operand.Op) { ctx.MULPS(mx, x) } + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +// Construct and append a MULQ instruction to the active function. +func (c *Context) MULQ(mr operand.Op) { + if inst, err := x86.MULQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +// Construct and append a MULQ instruction to the active function. +// Operates on the global context. +func MULQ(mr operand.Op) { ctx.MULQ(mr) } + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +// Construct and append a MULSD instruction to the active function. +func (c *Context) MULSD(mx, x operand.Op) { + if inst, err := x86.MULSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +// Construct and append a MULSD instruction to the active function. +// Operates on the global context. +func MULSD(mx, x operand.Op) { ctx.MULSD(mx, x) } + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +// Construct and append a MULSS instruction to the active function. +func (c *Context) MULSS(mx, x operand.Op) { + if inst, err := x86.MULSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +// Construct and append a MULSS instruction to the active function. +// Operates on the global context. +func MULSS(mx, x operand.Op) { ctx.MULSS(mx, x) } + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +// Construct and append a MULW instruction to the active function. +func (c *Context) MULW(mr operand.Op) { + if inst, err := x86.MULW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +// Construct and append a MULW instruction to the active function. +// Operates on the global context. +func MULW(mr operand.Op) { ctx.MULW(mr) } + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +// Construct and append a MULXL instruction to the active function. +func (c *Context) MULXL(mr, r, r1 operand.Op) { + if inst, err := x86.MULXL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +// Construct and append a MULXL instruction to the active function. +// Operates on the global context. +func MULXL(mr, r, r1 operand.Op) { ctx.MULXL(mr, r, r1) } + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +// Construct and append a MULXQ instruction to the active function. +func (c *Context) MULXQ(mr, r, r1 operand.Op) { + if inst, err := x86.MULXQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +// Construct and append a MULXQ instruction to the active function. +// Operates on the global context. +func MULXQ(mr, r, r1 operand.Op) { ctx.MULXQ(mr, r, r1) } + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +// Construct and append a MWAIT instruction to the active function. +func (c *Context) MWAIT() { + if inst, err := x86.MWAIT(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +// Construct and append a MWAIT instruction to the active function. +// Operates on the global context. +func MWAIT() { ctx.MWAIT() } + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +// Construct and append a NEGB instruction to the active function. +func (c *Context) NEGB(mr operand.Op) { + if inst, err := x86.NEGB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +// Construct and append a NEGB instruction to the active function. +// Operates on the global context. +func NEGB(mr operand.Op) { ctx.NEGB(mr) } + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +// Construct and append a NEGL instruction to the active function. +func (c *Context) NEGL(mr operand.Op) { + if inst, err := x86.NEGL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +// Construct and append a NEGL instruction to the active function. +// Operates on the global context. +func NEGL(mr operand.Op) { ctx.NEGL(mr) } + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +// Construct and append a NEGQ instruction to the active function. +func (c *Context) NEGQ(mr operand.Op) { + if inst, err := x86.NEGQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +// Construct and append a NEGQ instruction to the active function. +// Operates on the global context. +func NEGQ(mr operand.Op) { ctx.NEGQ(mr) } + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +// Construct and append a NEGW instruction to the active function. +func (c *Context) NEGW(mr operand.Op) { + if inst, err := x86.NEGW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +// Construct and append a NEGW instruction to the active function. +// Operates on the global context. +func NEGW(mr operand.Op) { ctx.NEGW(mr) } + +// NOP: No Operation. +// +// Forms: +// +// NOP +// Construct and append a NOP instruction to the active function. +func (c *Context) NOP() { + if inst, err := x86.NOP(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOP: No Operation. +// +// Forms: +// +// NOP +// Construct and append a NOP instruction to the active function. +// Operates on the global context. +func NOP() { ctx.NOP() } + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +// Construct and append a NOTB instruction to the active function. +func (c *Context) NOTB(mr operand.Op) { + if inst, err := x86.NOTB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +// Construct and append a NOTB instruction to the active function. +// Operates on the global context. +func NOTB(mr operand.Op) { ctx.NOTB(mr) } + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +// Construct and append a NOTL instruction to the active function. +func (c *Context) NOTL(mr operand.Op) { + if inst, err := x86.NOTL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +// Construct and append a NOTL instruction to the active function. +// Operates on the global context. +func NOTL(mr operand.Op) { ctx.NOTL(mr) } + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +// Construct and append a NOTQ instruction to the active function. +func (c *Context) NOTQ(mr operand.Op) { + if inst, err := x86.NOTQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +// Construct and append a NOTQ instruction to the active function. +// Operates on the global context. +func NOTQ(mr operand.Op) { ctx.NOTQ(mr) } + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +// Construct and append a NOTW instruction to the active function. +func (c *Context) NOTW(mr operand.Op) { + if inst, err := x86.NOTW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +// Construct and append a NOTW instruction to the active function. +// Operates on the global context. +func NOTW(mr operand.Op) { ctx.NOTW(mr) } + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +// Construct and append a ORB instruction to the active function. +func (c *Context) ORB(imr, amr operand.Op) { + if inst, err := x86.ORB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +// Construct and append a ORB instruction to the active function. +// Operates on the global context. +func ORB(imr, amr operand.Op) { ctx.ORB(imr, amr) } + +// 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 +// Construct and append a ORL instruction to the active function. +func (c *Context) ORL(imr, emr operand.Op) { + if inst, err := x86.ORL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ORL instruction to the active function. +// Operates on the global context. +func ORL(imr, emr operand.Op) { ctx.ORL(imr, emr) } + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +// Construct and append a ORPD instruction to the active function. +func (c *Context) ORPD(mx, x operand.Op) { + if inst, err := x86.ORPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +// Construct and append a ORPD instruction to the active function. +// Operates on the global context. +func ORPD(mx, x operand.Op) { ctx.ORPD(mx, x) } + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +// Construct and append a ORPS instruction to the active function. +func (c *Context) ORPS(mx, x operand.Op) { + if inst, err := x86.ORPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +// Construct and append a ORPS instruction to the active function. +// Operates on the global context. +func ORPS(mx, x operand.Op) { ctx.ORPS(mx, x) } + +// 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 +// Construct and append a ORQ instruction to the active function. +func (c *Context) ORQ(imr, mr operand.Op) { + if inst, err := x86.ORQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ORQ instruction to the active function. +// Operates on the global context. +func ORQ(imr, mr operand.Op) { ctx.ORQ(imr, mr) } + +// 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 +// Construct and append a ORW instruction to the active function. +func (c *Context) ORW(imr, amr operand.Op) { + if inst, err := x86.ORW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a ORW instruction to the active function. +// Operates on the global context. +func ORW(imr, amr operand.Op) { ctx.ORW(imr, amr) } + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +// Construct and append a PABSB instruction to the active function. +func (c *Context) PABSB(mx, x operand.Op) { + if inst, err := x86.PABSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +// Construct and append a PABSB instruction to the active function. +// Operates on the global context. +func PABSB(mx, x operand.Op) { ctx.PABSB(mx, x) } + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +// Construct and append a PABSD instruction to the active function. +func (c *Context) PABSD(mx, x operand.Op) { + if inst, err := x86.PABSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +// Construct and append a PABSD instruction to the active function. +// Operates on the global context. +func PABSD(mx, x operand.Op) { ctx.PABSD(mx, x) } + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +// Construct and append a PABSW instruction to the active function. +func (c *Context) PABSW(mx, x operand.Op) { + if inst, err := x86.PABSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +// Construct and append a PABSW instruction to the active function. +// Operates on the global context. +func PABSW(mx, x operand.Op) { ctx.PABSW(mx, x) } + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +// Construct and append a PACKSSLW instruction to the active function. +func (c *Context) PACKSSLW(mx, x operand.Op) { + if inst, err := x86.PACKSSLW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +// Construct and append a PACKSSLW instruction to the active function. +// Operates on the global context. +func PACKSSLW(mx, x operand.Op) { ctx.PACKSSLW(mx, x) } + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +// Construct and append a PACKSSWB instruction to the active function. +func (c *Context) PACKSSWB(mx, x operand.Op) { + if inst, err := x86.PACKSSWB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +// Construct and append a PACKSSWB instruction to the active function. +// Operates on the global context. +func PACKSSWB(mx, x operand.Op) { ctx.PACKSSWB(mx, x) } + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +// Construct and append a PACKUSDW instruction to the active function. +func (c *Context) PACKUSDW(mx, x operand.Op) { + if inst, err := x86.PACKUSDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +// Construct and append a PACKUSDW instruction to the active function. +// Operates on the global context. +func PACKUSDW(mx, x operand.Op) { ctx.PACKUSDW(mx, x) } + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +// Construct and append a PACKUSWB instruction to the active function. +func (c *Context) PACKUSWB(mx, x operand.Op) { + if inst, err := x86.PACKUSWB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +// Construct and append a PACKUSWB instruction to the active function. +// Operates on the global context. +func PACKUSWB(mx, x operand.Op) { ctx.PACKUSWB(mx, x) } + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +// Construct and append a PADDB instruction to the active function. +func (c *Context) PADDB(mx, x operand.Op) { + if inst, err := x86.PADDB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +// Construct and append a PADDB instruction to the active function. +// Operates on the global context. +func PADDB(mx, x operand.Op) { ctx.PADDB(mx, x) } + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +// Construct and append a PADDD instruction to the active function. +func (c *Context) PADDD(mx, x operand.Op) { + if inst, err := x86.PADDD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +// Construct and append a PADDD instruction to the active function. +// Operates on the global context. +func PADDD(mx, x operand.Op) { ctx.PADDD(mx, x) } + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +// Construct and append a PADDL instruction to the active function. +func (c *Context) PADDL(mx, x operand.Op) { + if inst, err := x86.PADDL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +// Construct and append a PADDL instruction to the active function. +// Operates on the global context. +func PADDL(mx, x operand.Op) { ctx.PADDL(mx, x) } + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +// Construct and append a PADDQ instruction to the active function. +func (c *Context) PADDQ(mx, x operand.Op) { + if inst, err := x86.PADDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +// Construct and append a PADDQ instruction to the active function. +// Operates on the global context. +func PADDQ(mx, x operand.Op) { ctx.PADDQ(mx, x) } + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +// Construct and append a PADDSB instruction to the active function. +func (c *Context) PADDSB(mx, x operand.Op) { + if inst, err := x86.PADDSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +// Construct and append a PADDSB instruction to the active function. +// Operates on the global context. +func PADDSB(mx, x operand.Op) { ctx.PADDSB(mx, x) } + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +// Construct and append a PADDSW instruction to the active function. +func (c *Context) PADDSW(mx, x operand.Op) { + if inst, err := x86.PADDSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +// Construct and append a PADDSW instruction to the active function. +// Operates on the global context. +func PADDSW(mx, x operand.Op) { ctx.PADDSW(mx, x) } + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +// Construct and append a PADDUSB instruction to the active function. +func (c *Context) PADDUSB(mx, x operand.Op) { + if inst, err := x86.PADDUSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +// Construct and append a PADDUSB instruction to the active function. +// Operates on the global context. +func PADDUSB(mx, x operand.Op) { ctx.PADDUSB(mx, x) } + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +// Construct and append a PADDUSW instruction to the active function. +func (c *Context) PADDUSW(mx, x operand.Op) { + if inst, err := x86.PADDUSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +// Construct and append a PADDUSW instruction to the active function. +// Operates on the global context. +func PADDUSW(mx, x operand.Op) { ctx.PADDUSW(mx, x) } + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +// Construct and append a PADDW instruction to the active function. +func (c *Context) PADDW(mx, x operand.Op) { + if inst, err := x86.PADDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +// Construct and append a PADDW instruction to the active function. +// Operates on the global context. +func PADDW(mx, x operand.Op) { ctx.PADDW(mx, x) } + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +// Construct and append a PALIGNR instruction to the active function. +func (c *Context) PALIGNR(i, mx, x operand.Op) { + if inst, err := x86.PALIGNR(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +// Construct and append a PALIGNR instruction to the active function. +// Operates on the global context. +func PALIGNR(i, mx, x operand.Op) { ctx.PALIGNR(i, mx, x) } + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +// Construct and append a PAND instruction to the active function. +func (c *Context) PAND(mx, x operand.Op) { + if inst, err := x86.PAND(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +// Construct and append a PAND instruction to the active function. +// Operates on the global context. +func PAND(mx, x operand.Op) { ctx.PAND(mx, x) } + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +// Construct and append a PANDN instruction to the active function. +func (c *Context) PANDN(mx, x operand.Op) { + if inst, err := x86.PANDN(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +// Construct and append a PANDN instruction to the active function. +// Operates on the global context. +func PANDN(mx, x operand.Op) { ctx.PANDN(mx, x) } + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +// Construct and append a PAUSE instruction to the active function. +func (c *Context) PAUSE() { + if inst, err := x86.PAUSE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +// Construct and append a PAUSE instruction to the active function. +// Operates on the global context. +func PAUSE() { ctx.PAUSE() } + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +// Construct and append a PAVGB instruction to the active function. +func (c *Context) PAVGB(mx, x operand.Op) { + if inst, err := x86.PAVGB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +// Construct and append a PAVGB instruction to the active function. +// Operates on the global context. +func PAVGB(mx, x operand.Op) { ctx.PAVGB(mx, x) } + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +// Construct and append a PAVGW instruction to the active function. +func (c *Context) PAVGW(mx, x operand.Op) { + if inst, err := x86.PAVGW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +// Construct and append a PAVGW instruction to the active function. +// Operates on the global context. +func PAVGW(mx, x operand.Op) { ctx.PAVGW(mx, x) } + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +// Construct and append a PBLENDVB instruction to the active function. +func (c *Context) PBLENDVB(x, mx, x1 operand.Op) { + if inst, err := x86.PBLENDVB(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +// Construct and append a PBLENDVB instruction to the active function. +// Operates on the global context. +func PBLENDVB(x, mx, x1 operand.Op) { ctx.PBLENDVB(x, mx, x1) } + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +// Construct and append a PBLENDW instruction to the active function. +func (c *Context) PBLENDW(i, mx, x operand.Op) { + if inst, err := x86.PBLENDW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +// Construct and append a PBLENDW instruction to the active function. +// Operates on the global context. +func PBLENDW(i, mx, x operand.Op) { ctx.PBLENDW(i, mx, x) } + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +// Construct and append a PCLMULQDQ instruction to the active function. +func (c *Context) PCLMULQDQ(i, mx, x operand.Op) { + if inst, err := x86.PCLMULQDQ(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +// Construct and append a PCLMULQDQ instruction to the active function. +// Operates on the global context. +func PCLMULQDQ(i, mx, x operand.Op) { ctx.PCLMULQDQ(i, mx, x) } + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +// Construct and append a PCMPEQB instruction to the active function. +func (c *Context) PCMPEQB(mx, x operand.Op) { + if inst, err := x86.PCMPEQB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +// Construct and append a PCMPEQB instruction to the active function. +// Operates on the global context. +func PCMPEQB(mx, x operand.Op) { ctx.PCMPEQB(mx, x) } + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +// Construct and append a PCMPEQL instruction to the active function. +func (c *Context) PCMPEQL(mx, x operand.Op) { + if inst, err := x86.PCMPEQL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +// Construct and append a PCMPEQL instruction to the active function. +// Operates on the global context. +func PCMPEQL(mx, x operand.Op) { ctx.PCMPEQL(mx, x) } + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +// Construct and append a PCMPEQQ instruction to the active function. +func (c *Context) PCMPEQQ(mx, x operand.Op) { + if inst, err := x86.PCMPEQQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +// Construct and append a PCMPEQQ instruction to the active function. +// Operates on the global context. +func PCMPEQQ(mx, x operand.Op) { ctx.PCMPEQQ(mx, x) } + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +// Construct and append a PCMPEQW instruction to the active function. +func (c *Context) PCMPEQW(mx, x operand.Op) { + if inst, err := x86.PCMPEQW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +// Construct and append a PCMPEQW instruction to the active function. +// Operates on the global context. +func PCMPEQW(mx, x operand.Op) { ctx.PCMPEQW(mx, x) } + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +// Construct and append a PCMPESTRI instruction to the active function. +func (c *Context) PCMPESTRI(i, mx, x operand.Op) { + if inst, err := x86.PCMPESTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +// Construct and append a PCMPESTRI instruction to the active function. +// Operates on the global context. +func PCMPESTRI(i, mx, x operand.Op) { ctx.PCMPESTRI(i, mx, x) } + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +// Construct and append a PCMPESTRM instruction to the active function. +func (c *Context) PCMPESTRM(i, mx, x operand.Op) { + if inst, err := x86.PCMPESTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +// Construct and append a PCMPESTRM instruction to the active function. +// Operates on the global context. +func PCMPESTRM(i, mx, x operand.Op) { ctx.PCMPESTRM(i, mx, x) } + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +// Construct and append a PCMPGTB instruction to the active function. +func (c *Context) PCMPGTB(mx, x operand.Op) { + if inst, err := x86.PCMPGTB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +// Construct and append a PCMPGTB instruction to the active function. +// Operates on the global context. +func PCMPGTB(mx, x operand.Op) { ctx.PCMPGTB(mx, x) } + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +// Construct and append a PCMPGTL instruction to the active function. +func (c *Context) PCMPGTL(mx, x operand.Op) { + if inst, err := x86.PCMPGTL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +// Construct and append a PCMPGTL instruction to the active function. +// Operates on the global context. +func PCMPGTL(mx, x operand.Op) { ctx.PCMPGTL(mx, x) } + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +// Construct and append a PCMPGTQ instruction to the active function. +func (c *Context) PCMPGTQ(mx, x operand.Op) { + if inst, err := x86.PCMPGTQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +// Construct and append a PCMPGTQ instruction to the active function. +// Operates on the global context. +func PCMPGTQ(mx, x operand.Op) { ctx.PCMPGTQ(mx, x) } + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +// Construct and append a PCMPGTW instruction to the active function. +func (c *Context) PCMPGTW(mx, x operand.Op) { + if inst, err := x86.PCMPGTW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +// Construct and append a PCMPGTW instruction to the active function. +// Operates on the global context. +func PCMPGTW(mx, x operand.Op) { ctx.PCMPGTW(mx, x) } + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +// Construct and append a PCMPISTRI instruction to the active function. +func (c *Context) PCMPISTRI(i, mx, x operand.Op) { + if inst, err := x86.PCMPISTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +// Construct and append a PCMPISTRI instruction to the active function. +// Operates on the global context. +func PCMPISTRI(i, mx, x operand.Op) { ctx.PCMPISTRI(i, mx, x) } + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +// Construct and append a PCMPISTRM instruction to the active function. +func (c *Context) PCMPISTRM(i, mx, x operand.Op) { + if inst, err := x86.PCMPISTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +// Construct and append a PCMPISTRM instruction to the active function. +// Operates on the global context. +func PCMPISTRM(i, mx, x operand.Op) { ctx.PCMPISTRM(i, mx, x) } + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +// Construct and append a PDEPL instruction to the active function. +func (c *Context) PDEPL(mr, r, r1 operand.Op) { + if inst, err := x86.PDEPL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +// Construct and append a PDEPL instruction to the active function. +// Operates on the global context. +func PDEPL(mr, r, r1 operand.Op) { ctx.PDEPL(mr, r, r1) } + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +// Construct and append a PDEPQ instruction to the active function. +func (c *Context) PDEPQ(mr, r, r1 operand.Op) { + if inst, err := x86.PDEPQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +// Construct and append a PDEPQ instruction to the active function. +// Operates on the global context. +func PDEPQ(mr, r, r1 operand.Op) { ctx.PDEPQ(mr, r, r1) } + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +// Construct and append a PEXTL instruction to the active function. +func (c *Context) PEXTL(mr, r, r1 operand.Op) { + if inst, err := x86.PEXTL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +// Construct and append a PEXTL instruction to the active function. +// Operates on the global context. +func PEXTL(mr, r, r1 operand.Op) { ctx.PEXTL(mr, r, r1) } + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +// Construct and append a PEXTQ instruction to the active function. +func (c *Context) PEXTQ(mr, r, r1 operand.Op) { + if inst, err := x86.PEXTQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +// Construct and append a PEXTQ instruction to the active function. +// Operates on the global context. +func PEXTQ(mr, r, r1 operand.Op) { ctx.PEXTQ(mr, r, r1) } + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +// Construct and append a PEXTRB instruction to the active function. +func (c *Context) PEXTRB(i, x, mr operand.Op) { + if inst, err := x86.PEXTRB(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +// Construct and append a PEXTRB instruction to the active function. +// Operates on the global context. +func PEXTRB(i, x, mr operand.Op) { ctx.PEXTRB(i, x, mr) } + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +// Construct and append a PEXTRD instruction to the active function. +func (c *Context) PEXTRD(i, x, mr operand.Op) { + if inst, err := x86.PEXTRD(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +// Construct and append a PEXTRD instruction to the active function. +// Operates on the global context. +func PEXTRD(i, x, mr operand.Op) { ctx.PEXTRD(i, x, mr) } + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +// Construct and append a PEXTRQ instruction to the active function. +func (c *Context) PEXTRQ(i, x, mr operand.Op) { + if inst, err := x86.PEXTRQ(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +// Construct and append a PEXTRQ instruction to the active function. +// Operates on the global context. +func PEXTRQ(i, x, mr operand.Op) { ctx.PEXTRQ(i, x, mr) } + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +// Construct and append a PEXTRW instruction to the active function. +func (c *Context) PEXTRW(i, x, mr operand.Op) { + if inst, err := x86.PEXTRW(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +// Construct and append a PEXTRW instruction to the active function. +// Operates on the global context. +func PEXTRW(i, x, mr operand.Op) { ctx.PEXTRW(i, x, mr) } + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +// Construct and append a PHADDD instruction to the active function. +func (c *Context) PHADDD(mx, x operand.Op) { + if inst, err := x86.PHADDD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +// Construct and append a PHADDD instruction to the active function. +// Operates on the global context. +func PHADDD(mx, x operand.Op) { ctx.PHADDD(mx, x) } + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +// Construct and append a PHADDSW instruction to the active function. +func (c *Context) PHADDSW(mx, x operand.Op) { + if inst, err := x86.PHADDSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +// Construct and append a PHADDSW instruction to the active function. +// Operates on the global context. +func PHADDSW(mx, x operand.Op) { ctx.PHADDSW(mx, x) } + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +// Construct and append a PHADDW instruction to the active function. +func (c *Context) PHADDW(mx, x operand.Op) { + if inst, err := x86.PHADDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +// Construct and append a PHADDW instruction to the active function. +// Operates on the global context. +func PHADDW(mx, x operand.Op) { ctx.PHADDW(mx, x) } + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +// Construct and append a PHMINPOSUW instruction to the active function. +func (c *Context) PHMINPOSUW(mx, x operand.Op) { + if inst, err := x86.PHMINPOSUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +// Construct and append a PHMINPOSUW instruction to the active function. +// Operates on the global context. +func PHMINPOSUW(mx, x operand.Op) { ctx.PHMINPOSUW(mx, x) } + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +// Construct and append a PHSUBD instruction to the active function. +func (c *Context) PHSUBD(mx, x operand.Op) { + if inst, err := x86.PHSUBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +// Construct and append a PHSUBD instruction to the active function. +// Operates on the global context. +func PHSUBD(mx, x operand.Op) { ctx.PHSUBD(mx, x) } + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +// Construct and append a PHSUBSW instruction to the active function. +func (c *Context) PHSUBSW(mx, x operand.Op) { + if inst, err := x86.PHSUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +// Construct and append a PHSUBSW instruction to the active function. +// Operates on the global context. +func PHSUBSW(mx, x operand.Op) { ctx.PHSUBSW(mx, x) } + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +// Construct and append a PHSUBW instruction to the active function. +func (c *Context) PHSUBW(mx, x operand.Op) { + if inst, err := x86.PHSUBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +// Construct and append a PHSUBW instruction to the active function. +// Operates on the global context. +func PHSUBW(mx, x operand.Op) { ctx.PHSUBW(mx, x) } + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +// Construct and append a PINSRB instruction to the active function. +func (c *Context) PINSRB(i, mr, x operand.Op) { + if inst, err := x86.PINSRB(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +// Construct and append a PINSRB instruction to the active function. +// Operates on the global context. +func PINSRB(i, mr, x operand.Op) { ctx.PINSRB(i, mr, x) } + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +// Construct and append a PINSRD instruction to the active function. +func (c *Context) PINSRD(i, mr, x operand.Op) { + if inst, err := x86.PINSRD(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +// Construct and append a PINSRD instruction to the active function. +// Operates on the global context. +func PINSRD(i, mr, x operand.Op) { ctx.PINSRD(i, mr, x) } + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +// Construct and append a PINSRQ instruction to the active function. +func (c *Context) PINSRQ(i, mr, x operand.Op) { + if inst, err := x86.PINSRQ(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +// Construct and append a PINSRQ instruction to the active function. +// Operates on the global context. +func PINSRQ(i, mr, x operand.Op) { ctx.PINSRQ(i, mr, x) } + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +// Construct and append a PINSRW instruction to the active function. +func (c *Context) PINSRW(i, mr, x operand.Op) { + if inst, err := x86.PINSRW(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +// Construct and append a PINSRW instruction to the active function. +// Operates on the global context. +func PINSRW(i, mr, x operand.Op) { ctx.PINSRW(i, mr, x) } + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +// Construct and append a PMADDUBSW instruction to the active function. +func (c *Context) PMADDUBSW(mx, x operand.Op) { + if inst, err := x86.PMADDUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +// Construct and append a PMADDUBSW instruction to the active function. +// Operates on the global context. +func PMADDUBSW(mx, x operand.Op) { ctx.PMADDUBSW(mx, x) } + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +// Construct and append a PMADDWL instruction to the active function. +func (c *Context) PMADDWL(mx, x operand.Op) { + if inst, err := x86.PMADDWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +// Construct and append a PMADDWL instruction to the active function. +// Operates on the global context. +func PMADDWL(mx, x operand.Op) { ctx.PMADDWL(mx, x) } + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +// Construct and append a PMAXSB instruction to the active function. +func (c *Context) PMAXSB(mx, x operand.Op) { + if inst, err := x86.PMAXSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +// Construct and append a PMAXSB instruction to the active function. +// Operates on the global context. +func PMAXSB(mx, x operand.Op) { ctx.PMAXSB(mx, x) } + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +// Construct and append a PMAXSD instruction to the active function. +func (c *Context) PMAXSD(mx, x operand.Op) { + if inst, err := x86.PMAXSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +// Construct and append a PMAXSD instruction to the active function. +// Operates on the global context. +func PMAXSD(mx, x operand.Op) { ctx.PMAXSD(mx, x) } + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +// Construct and append a PMAXSW instruction to the active function. +func (c *Context) PMAXSW(mx, x operand.Op) { + if inst, err := x86.PMAXSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +// Construct and append a PMAXSW instruction to the active function. +// Operates on the global context. +func PMAXSW(mx, x operand.Op) { ctx.PMAXSW(mx, x) } + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +// Construct and append a PMAXUB instruction to the active function. +func (c *Context) PMAXUB(mx, x operand.Op) { + if inst, err := x86.PMAXUB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +// Construct and append a PMAXUB instruction to the active function. +// Operates on the global context. +func PMAXUB(mx, x operand.Op) { ctx.PMAXUB(mx, x) } + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +// Construct and append a PMAXUD instruction to the active function. +func (c *Context) PMAXUD(mx, x operand.Op) { + if inst, err := x86.PMAXUD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +// Construct and append a PMAXUD instruction to the active function. +// Operates on the global context. +func PMAXUD(mx, x operand.Op) { ctx.PMAXUD(mx, x) } + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +// Construct and append a PMAXUW instruction to the active function. +func (c *Context) PMAXUW(mx, x operand.Op) { + if inst, err := x86.PMAXUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +// Construct and append a PMAXUW instruction to the active function. +// Operates on the global context. +func PMAXUW(mx, x operand.Op) { ctx.PMAXUW(mx, x) } + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +// Construct and append a PMINSB instruction to the active function. +func (c *Context) PMINSB(mx, x operand.Op) { + if inst, err := x86.PMINSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +// Construct and append a PMINSB instruction to the active function. +// Operates on the global context. +func PMINSB(mx, x operand.Op) { ctx.PMINSB(mx, x) } + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +// Construct and append a PMINSD instruction to the active function. +func (c *Context) PMINSD(mx, x operand.Op) { + if inst, err := x86.PMINSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +// Construct and append a PMINSD instruction to the active function. +// Operates on the global context. +func PMINSD(mx, x operand.Op) { ctx.PMINSD(mx, x) } + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +// Construct and append a PMINSW instruction to the active function. +func (c *Context) PMINSW(mx, x operand.Op) { + if inst, err := x86.PMINSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +// Construct and append a PMINSW instruction to the active function. +// Operates on the global context. +func PMINSW(mx, x operand.Op) { ctx.PMINSW(mx, x) } + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +// Construct and append a PMINUB instruction to the active function. +func (c *Context) PMINUB(mx, x operand.Op) { + if inst, err := x86.PMINUB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +// Construct and append a PMINUB instruction to the active function. +// Operates on the global context. +func PMINUB(mx, x operand.Op) { ctx.PMINUB(mx, x) } + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +// Construct and append a PMINUD instruction to the active function. +func (c *Context) PMINUD(mx, x operand.Op) { + if inst, err := x86.PMINUD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +// Construct and append a PMINUD instruction to the active function. +// Operates on the global context. +func PMINUD(mx, x operand.Op) { ctx.PMINUD(mx, x) } + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +// Construct and append a PMINUW instruction to the active function. +func (c *Context) PMINUW(mx, x operand.Op) { + if inst, err := x86.PMINUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +// Construct and append a PMINUW instruction to the active function. +// Operates on the global context. +func PMINUW(mx, x operand.Op) { ctx.PMINUW(mx, x) } + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +// Construct and append a PMOVMSKB instruction to the active function. +func (c *Context) PMOVMSKB(x, r operand.Op) { + if inst, err := x86.PMOVMSKB(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +// Construct and append a PMOVMSKB instruction to the active function. +// Operates on the global context. +func PMOVMSKB(x, r operand.Op) { ctx.PMOVMSKB(x, r) } + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +// Construct and append a PMOVSXBD instruction to the active function. +func (c *Context) PMOVSXBD(mx, x operand.Op) { + if inst, err := x86.PMOVSXBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +// Construct and append a PMOVSXBD instruction to the active function. +// Operates on the global context. +func PMOVSXBD(mx, x operand.Op) { ctx.PMOVSXBD(mx, x) } + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +// Construct and append a PMOVSXBQ instruction to the active function. +func (c *Context) PMOVSXBQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +// Construct and append a PMOVSXBQ instruction to the active function. +// Operates on the global context. +func PMOVSXBQ(mx, x operand.Op) { ctx.PMOVSXBQ(mx, x) } + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +// Construct and append a PMOVSXBW instruction to the active function. +func (c *Context) PMOVSXBW(mx, x operand.Op) { + if inst, err := x86.PMOVSXBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +// Construct and append a PMOVSXBW instruction to the active function. +// Operates on the global context. +func PMOVSXBW(mx, x operand.Op) { ctx.PMOVSXBW(mx, x) } + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +// Construct and append a PMOVSXDQ instruction to the active function. +func (c *Context) PMOVSXDQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +// Construct and append a PMOVSXDQ instruction to the active function. +// Operates on the global context. +func PMOVSXDQ(mx, x operand.Op) { ctx.PMOVSXDQ(mx, x) } + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +// Construct and append a PMOVSXWD instruction to the active function. +func (c *Context) PMOVSXWD(mx, x operand.Op) { + if inst, err := x86.PMOVSXWD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +// Construct and append a PMOVSXWD instruction to the active function. +// Operates on the global context. +func PMOVSXWD(mx, x operand.Op) { ctx.PMOVSXWD(mx, x) } + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +// Construct and append a PMOVSXWQ instruction to the active function. +func (c *Context) PMOVSXWQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXWQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +// Construct and append a PMOVSXWQ instruction to the active function. +// Operates on the global context. +func PMOVSXWQ(mx, x operand.Op) { ctx.PMOVSXWQ(mx, x) } + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +// Construct and append a PMOVZXBD instruction to the active function. +func (c *Context) PMOVZXBD(mx, x operand.Op) { + if inst, err := x86.PMOVZXBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +// Construct and append a PMOVZXBD instruction to the active function. +// Operates on the global context. +func PMOVZXBD(mx, x operand.Op) { ctx.PMOVZXBD(mx, x) } + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +// Construct and append a PMOVZXBQ instruction to the active function. +func (c *Context) PMOVZXBQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +// Construct and append a PMOVZXBQ instruction to the active function. +// Operates on the global context. +func PMOVZXBQ(mx, x operand.Op) { ctx.PMOVZXBQ(mx, x) } + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +// Construct and append a PMOVZXBW instruction to the active function. +func (c *Context) PMOVZXBW(mx, x operand.Op) { + if inst, err := x86.PMOVZXBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +// Construct and append a PMOVZXBW instruction to the active function. +// Operates on the global context. +func PMOVZXBW(mx, x operand.Op) { ctx.PMOVZXBW(mx, x) } + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +// Construct and append a PMOVZXDQ instruction to the active function. +func (c *Context) PMOVZXDQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +// Construct and append a PMOVZXDQ instruction to the active function. +// Operates on the global context. +func PMOVZXDQ(mx, x operand.Op) { ctx.PMOVZXDQ(mx, x) } + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +// Construct and append a PMOVZXWD instruction to the active function. +func (c *Context) PMOVZXWD(mx, x operand.Op) { + if inst, err := x86.PMOVZXWD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +// Construct and append a PMOVZXWD instruction to the active function. +// Operates on the global context. +func PMOVZXWD(mx, x operand.Op) { ctx.PMOVZXWD(mx, x) } + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +// Construct and append a PMOVZXWQ instruction to the active function. +func (c *Context) PMOVZXWQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXWQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +// Construct and append a PMOVZXWQ instruction to the active function. +// Operates on the global context. +func PMOVZXWQ(mx, x operand.Op) { ctx.PMOVZXWQ(mx, x) } + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +// Construct and append a PMULDQ instruction to the active function. +func (c *Context) PMULDQ(mx, x operand.Op) { + if inst, err := x86.PMULDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +// Construct and append a PMULDQ instruction to the active function. +// Operates on the global context. +func PMULDQ(mx, x operand.Op) { ctx.PMULDQ(mx, x) } + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +// Construct and append a PMULHRSW instruction to the active function. +func (c *Context) PMULHRSW(mx, x operand.Op) { + if inst, err := x86.PMULHRSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +// Construct and append a PMULHRSW instruction to the active function. +// Operates on the global context. +func PMULHRSW(mx, x operand.Op) { ctx.PMULHRSW(mx, x) } + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +// Construct and append a PMULHUW instruction to the active function. +func (c *Context) PMULHUW(mx, x operand.Op) { + if inst, err := x86.PMULHUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +// Construct and append a PMULHUW instruction to the active function. +// Operates on the global context. +func PMULHUW(mx, x operand.Op) { ctx.PMULHUW(mx, x) } + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +// Construct and append a PMULHW instruction to the active function. +func (c *Context) PMULHW(mx, x operand.Op) { + if inst, err := x86.PMULHW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +// Construct and append a PMULHW instruction to the active function. +// Operates on the global context. +func PMULHW(mx, x operand.Op) { ctx.PMULHW(mx, x) } + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +// Construct and append a PMULLD instruction to the active function. +func (c *Context) PMULLD(mx, x operand.Op) { + if inst, err := x86.PMULLD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +// Construct and append a PMULLD instruction to the active function. +// Operates on the global context. +func PMULLD(mx, x operand.Op) { ctx.PMULLD(mx, x) } + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +// Construct and append a PMULLW instruction to the active function. +func (c *Context) PMULLW(mx, x operand.Op) { + if inst, err := x86.PMULLW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +// Construct and append a PMULLW instruction to the active function. +// Operates on the global context. +func PMULLW(mx, x operand.Op) { ctx.PMULLW(mx, x) } + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +// Construct and append a PMULULQ instruction to the active function. +func (c *Context) PMULULQ(mx, x operand.Op) { + if inst, err := x86.PMULULQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +// Construct and append a PMULULQ instruction to the active function. +// Operates on the global context. +func PMULULQ(mx, x operand.Op) { ctx.PMULULQ(mx, x) } + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +// Construct and append a POPCNTL instruction to the active function. +func (c *Context) POPCNTL(mr, r operand.Op) { + if inst, err := x86.POPCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +// Construct and append a POPCNTL instruction to the active function. +// Operates on the global context. +func POPCNTL(mr, r operand.Op) { ctx.POPCNTL(mr, r) } + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +// Construct and append a POPCNTQ instruction to the active function. +func (c *Context) POPCNTQ(mr, r operand.Op) { + if inst, err := x86.POPCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +// Construct and append a POPCNTQ instruction to the active function. +// Operates on the global context. +func POPCNTQ(mr, r operand.Op) { ctx.POPCNTQ(mr, r) } + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +// Construct and append a POPCNTW instruction to the active function. +func (c *Context) POPCNTW(mr, r operand.Op) { + if inst, err := x86.POPCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +// Construct and append a POPCNTW instruction to the active function. +// Operates on the global context. +func POPCNTW(mr, r operand.Op) { ctx.POPCNTW(mr, r) } + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +// Construct and append a POPQ instruction to the active function. +func (c *Context) POPQ(mr operand.Op) { + if inst, err := x86.POPQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +// Construct and append a POPQ instruction to the active function. +// Operates on the global context. +func POPQ(mr operand.Op) { ctx.POPQ(mr) } + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +// Construct and append a POPW instruction to the active function. +func (c *Context) POPW(mr operand.Op) { + if inst, err := x86.POPW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +// Construct and append a POPW instruction to the active function. +// Operates on the global context. +func POPW(mr operand.Op) { ctx.POPW(mr) } + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +// Construct and append a POR instruction to the active function. +func (c *Context) POR(mx, x operand.Op) { + if inst, err := x86.POR(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +// Construct and append a POR instruction to the active function. +// Operates on the global context. +func POR(mx, x operand.Op) { ctx.POR(mx, x) } + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +// Construct and append a PREFETCHNTA instruction to the active function. +func (c *Context) PREFETCHNTA(m operand.Op) { + if inst, err := x86.PREFETCHNTA(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +// Construct and append a PREFETCHNTA instruction to the active function. +// Operates on the global context. +func PREFETCHNTA(m operand.Op) { ctx.PREFETCHNTA(m) } + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +// Construct and append a PREFETCHT0 instruction to the active function. +func (c *Context) PREFETCHT0(m operand.Op) { + if inst, err := x86.PREFETCHT0(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +// Construct and append a PREFETCHT0 instruction to the active function. +// Operates on the global context. +func PREFETCHT0(m operand.Op) { ctx.PREFETCHT0(m) } + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +// Construct and append a PREFETCHT1 instruction to the active function. +func (c *Context) PREFETCHT1(m operand.Op) { + if inst, err := x86.PREFETCHT1(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +// Construct and append a PREFETCHT1 instruction to the active function. +// Operates on the global context. +func PREFETCHT1(m operand.Op) { ctx.PREFETCHT1(m) } + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +// Construct and append a PREFETCHT2 instruction to the active function. +func (c *Context) PREFETCHT2(m operand.Op) { + if inst, err := x86.PREFETCHT2(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +// Construct and append a PREFETCHT2 instruction to the active function. +// Operates on the global context. +func PREFETCHT2(m operand.Op) { ctx.PREFETCHT2(m) } + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +// Construct and append a PSADBW instruction to the active function. +func (c *Context) PSADBW(mx, x operand.Op) { + if inst, err := x86.PSADBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +// Construct and append a PSADBW instruction to the active function. +// Operates on the global context. +func PSADBW(mx, x operand.Op) { ctx.PSADBW(mx, x) } + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +// Construct and append a PSHUFB instruction to the active function. +func (c *Context) PSHUFB(mx, x operand.Op) { + if inst, err := x86.PSHUFB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +// Construct and append a PSHUFB instruction to the active function. +// Operates on the global context. +func PSHUFB(mx, x operand.Op) { ctx.PSHUFB(mx, x) } + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +// Construct and append a PSHUFD instruction to the active function. +func (c *Context) PSHUFD(i, mx, x operand.Op) { + if inst, err := x86.PSHUFD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +// Construct and append a PSHUFD instruction to the active function. +// Operates on the global context. +func PSHUFD(i, mx, x operand.Op) { ctx.PSHUFD(i, mx, x) } + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +// Construct and append a PSHUFHW instruction to the active function. +func (c *Context) PSHUFHW(i, mx, x operand.Op) { + if inst, err := x86.PSHUFHW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +// Construct and append a PSHUFHW instruction to the active function. +// Operates on the global context. +func PSHUFHW(i, mx, x operand.Op) { ctx.PSHUFHW(i, mx, x) } + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +// Construct and append a PSHUFL instruction to the active function. +func (c *Context) PSHUFL(i, mx, x operand.Op) { + if inst, err := x86.PSHUFL(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +// Construct and append a PSHUFL instruction to the active function. +// Operates on the global context. +func PSHUFL(i, mx, x operand.Op) { ctx.PSHUFL(i, mx, x) } + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +// Construct and append a PSHUFLW instruction to the active function. +func (c *Context) PSHUFLW(i, mx, x operand.Op) { + if inst, err := x86.PSHUFLW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +// Construct and append a PSHUFLW instruction to the active function. +// Operates on the global context. +func PSHUFLW(i, mx, x operand.Op) { ctx.PSHUFLW(i, mx, x) } + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +// Construct and append a PSIGNB instruction to the active function. +func (c *Context) PSIGNB(mx, x operand.Op) { + if inst, err := x86.PSIGNB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +// Construct and append a PSIGNB instruction to the active function. +// Operates on the global context. +func PSIGNB(mx, x operand.Op) { ctx.PSIGNB(mx, x) } + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +// Construct and append a PSIGND instruction to the active function. +func (c *Context) PSIGND(mx, x operand.Op) { + if inst, err := x86.PSIGND(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +// Construct and append a PSIGND instruction to the active function. +// Operates on the global context. +func PSIGND(mx, x operand.Op) { ctx.PSIGND(mx, x) } + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +// Construct and append a PSIGNW instruction to the active function. +func (c *Context) PSIGNW(mx, x operand.Op) { + if inst, err := x86.PSIGNW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +// Construct and append a PSIGNW instruction to the active function. +// Operates on the global context. +func PSIGNW(mx, x operand.Op) { ctx.PSIGNW(mx, x) } + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +// Construct and append a PSLLDQ instruction to the active function. +func (c *Context) PSLLDQ(i, x operand.Op) { + if inst, err := x86.PSLLDQ(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +// Construct and append a PSLLDQ instruction to the active function. +// Operates on the global context. +func PSLLDQ(i, x operand.Op) { ctx.PSLLDQ(i, x) } + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +// Construct and append a PSLLL instruction to the active function. +func (c *Context) PSLLL(imx, x operand.Op) { + if inst, err := x86.PSLLL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +// Construct and append a PSLLL instruction to the active function. +// Operates on the global context. +func PSLLL(imx, x operand.Op) { ctx.PSLLL(imx, x) } + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +// Construct and append a PSLLO instruction to the active function. +func (c *Context) PSLLO(i, x operand.Op) { + if inst, err := x86.PSLLO(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +// Construct and append a PSLLO instruction to the active function. +// Operates on the global context. +func PSLLO(i, x operand.Op) { ctx.PSLLO(i, x) } + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +// Construct and append a PSLLQ instruction to the active function. +func (c *Context) PSLLQ(imx, x operand.Op) { + if inst, err := x86.PSLLQ(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +// Construct and append a PSLLQ instruction to the active function. +// Operates on the global context. +func PSLLQ(imx, x operand.Op) { ctx.PSLLQ(imx, x) } + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +// Construct and append a PSLLW instruction to the active function. +func (c *Context) PSLLW(imx, x operand.Op) { + if inst, err := x86.PSLLW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +// Construct and append a PSLLW instruction to the active function. +// Operates on the global context. +func PSLLW(imx, x operand.Op) { ctx.PSLLW(imx, x) } + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +// Construct and append a PSRAL instruction to the active function. +func (c *Context) PSRAL(imx, x operand.Op) { + if inst, err := x86.PSRAL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +// Construct and append a PSRAL instruction to the active function. +// Operates on the global context. +func PSRAL(imx, x operand.Op) { ctx.PSRAL(imx, x) } + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +// Construct and append a PSRAW instruction to the active function. +func (c *Context) PSRAW(imx, x operand.Op) { + if inst, err := x86.PSRAW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +// Construct and append a PSRAW instruction to the active function. +// Operates on the global context. +func PSRAW(imx, x operand.Op) { ctx.PSRAW(imx, x) } + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +// Construct and append a PSRLDQ instruction to the active function. +func (c *Context) PSRLDQ(i, x operand.Op) { + if inst, err := x86.PSRLDQ(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +// Construct and append a PSRLDQ instruction to the active function. +// Operates on the global context. +func PSRLDQ(i, x operand.Op) { ctx.PSRLDQ(i, x) } + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +// Construct and append a PSRLL instruction to the active function. +func (c *Context) PSRLL(imx, x operand.Op) { + if inst, err := x86.PSRLL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +// Construct and append a PSRLL instruction to the active function. +// Operates on the global context. +func PSRLL(imx, x operand.Op) { ctx.PSRLL(imx, x) } + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +// Construct and append a PSRLO instruction to the active function. +func (c *Context) PSRLO(i, x operand.Op) { + if inst, err := x86.PSRLO(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +// Construct and append a PSRLO instruction to the active function. +// Operates on the global context. +func PSRLO(i, x operand.Op) { ctx.PSRLO(i, x) } + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +// Construct and append a PSRLQ instruction to the active function. +func (c *Context) PSRLQ(imx, x operand.Op) { + if inst, err := x86.PSRLQ(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +// Construct and append a PSRLQ instruction to the active function. +// Operates on the global context. +func PSRLQ(imx, x operand.Op) { ctx.PSRLQ(imx, x) } + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +// Construct and append a PSRLW instruction to the active function. +func (c *Context) PSRLW(imx, x operand.Op) { + if inst, err := x86.PSRLW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +// Construct and append a PSRLW instruction to the active function. +// Operates on the global context. +func PSRLW(imx, x operand.Op) { ctx.PSRLW(imx, x) } + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +// Construct and append a PSUBB instruction to the active function. +func (c *Context) PSUBB(mx, x operand.Op) { + if inst, err := x86.PSUBB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +// Construct and append a PSUBB instruction to the active function. +// Operates on the global context. +func PSUBB(mx, x operand.Op) { ctx.PSUBB(mx, x) } + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +// Construct and append a PSUBL instruction to the active function. +func (c *Context) PSUBL(mx, x operand.Op) { + if inst, err := x86.PSUBL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +// Construct and append a PSUBL instruction to the active function. +// Operates on the global context. +func PSUBL(mx, x operand.Op) { ctx.PSUBL(mx, x) } + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +// Construct and append a PSUBQ instruction to the active function. +func (c *Context) PSUBQ(mx, x operand.Op) { + if inst, err := x86.PSUBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +// Construct and append a PSUBQ instruction to the active function. +// Operates on the global context. +func PSUBQ(mx, x operand.Op) { ctx.PSUBQ(mx, x) } + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +// Construct and append a PSUBSB instruction to the active function. +func (c *Context) PSUBSB(mx, x operand.Op) { + if inst, err := x86.PSUBSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +// Construct and append a PSUBSB instruction to the active function. +// Operates on the global context. +func PSUBSB(mx, x operand.Op) { ctx.PSUBSB(mx, x) } + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +// Construct and append a PSUBSW instruction to the active function. +func (c *Context) PSUBSW(mx, x operand.Op) { + if inst, err := x86.PSUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +// Construct and append a PSUBSW instruction to the active function. +// Operates on the global context. +func PSUBSW(mx, x operand.Op) { ctx.PSUBSW(mx, x) } + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +// Construct and append a PSUBUSB instruction to the active function. +func (c *Context) PSUBUSB(mx, x operand.Op) { + if inst, err := x86.PSUBUSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +// Construct and append a PSUBUSB instruction to the active function. +// Operates on the global context. +func PSUBUSB(mx, x operand.Op) { ctx.PSUBUSB(mx, x) } + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +// Construct and append a PSUBUSW instruction to the active function. +func (c *Context) PSUBUSW(mx, x operand.Op) { + if inst, err := x86.PSUBUSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +// Construct and append a PSUBUSW instruction to the active function. +// Operates on the global context. +func PSUBUSW(mx, x operand.Op) { ctx.PSUBUSW(mx, x) } + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +// Construct and append a PSUBW instruction to the active function. +func (c *Context) PSUBW(mx, x operand.Op) { + if inst, err := x86.PSUBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +// Construct and append a PSUBW instruction to the active function. +// Operates on the global context. +func PSUBW(mx, x operand.Op) { ctx.PSUBW(mx, x) } + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +// Construct and append a PTEST instruction to the active function. +func (c *Context) PTEST(mx, x operand.Op) { + if inst, err := x86.PTEST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +// Construct and append a PTEST instruction to the active function. +// Operates on the global context. +func PTEST(mx, x operand.Op) { ctx.PTEST(mx, x) } + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +// Construct and append a PUNPCKHBW instruction to the active function. +func (c *Context) PUNPCKHBW(mx, x operand.Op) { + if inst, err := x86.PUNPCKHBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +// Construct and append a PUNPCKHBW instruction to the active function. +// Operates on the global context. +func PUNPCKHBW(mx, x operand.Op) { ctx.PUNPCKHBW(mx, x) } + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +// Construct and append a PUNPCKHLQ instruction to the active function. +func (c *Context) PUNPCKHLQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKHLQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +// Construct and append a PUNPCKHLQ instruction to the active function. +// Operates on the global context. +func PUNPCKHLQ(mx, x operand.Op) { ctx.PUNPCKHLQ(mx, x) } + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +// Construct and append a PUNPCKHQDQ instruction to the active function. +func (c *Context) PUNPCKHQDQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKHQDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +// Construct and append a PUNPCKHQDQ instruction to the active function. +// Operates on the global context. +func PUNPCKHQDQ(mx, x operand.Op) { ctx.PUNPCKHQDQ(mx, x) } + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +// Construct and append a PUNPCKHWL instruction to the active function. +func (c *Context) PUNPCKHWL(mx, x operand.Op) { + if inst, err := x86.PUNPCKHWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +// Construct and append a PUNPCKHWL instruction to the active function. +// Operates on the global context. +func PUNPCKHWL(mx, x operand.Op) { ctx.PUNPCKHWL(mx, x) } + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +// Construct and append a PUNPCKLBW instruction to the active function. +func (c *Context) PUNPCKLBW(mx, x operand.Op) { + if inst, err := x86.PUNPCKLBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +// Construct and append a PUNPCKLBW instruction to the active function. +// Operates on the global context. +func PUNPCKLBW(mx, x operand.Op) { ctx.PUNPCKLBW(mx, x) } + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +// Construct and append a PUNPCKLLQ instruction to the active function. +func (c *Context) PUNPCKLLQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKLLQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +// Construct and append a PUNPCKLLQ instruction to the active function. +// Operates on the global context. +func PUNPCKLLQ(mx, x operand.Op) { ctx.PUNPCKLLQ(mx, x) } + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +// Construct and append a PUNPCKLQDQ instruction to the active function. +func (c *Context) PUNPCKLQDQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKLQDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +// Construct and append a PUNPCKLQDQ instruction to the active function. +// Operates on the global context. +func PUNPCKLQDQ(mx, x operand.Op) { ctx.PUNPCKLQDQ(mx, x) } + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +// Construct and append a PUNPCKLWL instruction to the active function. +func (c *Context) PUNPCKLWL(mx, x operand.Op) { + if inst, err := x86.PUNPCKLWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +// Construct and append a PUNPCKLWL instruction to the active function. +// Operates on the global context. +func PUNPCKLWL(mx, x operand.Op) { ctx.PUNPCKLWL(mx, x) } + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +// Construct and append a PUSHQ instruction to the active function. +func (c *Context) PUSHQ(imr operand.Op) { + if inst, err := x86.PUSHQ(imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +// Construct and append a PUSHQ instruction to the active function. +// Operates on the global context. +func PUSHQ(imr operand.Op) { ctx.PUSHQ(imr) } + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +// Construct and append a PUSHW instruction to the active function. +func (c *Context) PUSHW(mr operand.Op) { + if inst, err := x86.PUSHW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +// Construct and append a PUSHW instruction to the active function. +// Operates on the global context. +func PUSHW(mr operand.Op) { ctx.PUSHW(mr) } + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +// Construct and append a PXOR instruction to the active function. +func (c *Context) PXOR(mx, x operand.Op) { + if inst, err := x86.PXOR(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +// Construct and append a PXOR instruction to the active function. +// Operates on the global context. +func PXOR(mx, x operand.Op) { ctx.PXOR(mx, x) } + +// 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 +// Construct and append a RCLB instruction to the active function. +func (c *Context) RCLB(ci, mr operand.Op) { + if inst, err := x86.RCLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCLB instruction to the active function. +// Operates on the global context. +func RCLB(ci, mr operand.Op) { ctx.RCLB(ci, mr) } + +// 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 +// Construct and append a RCLL instruction to the active function. +func (c *Context) RCLL(ci, mr operand.Op) { + if inst, err := x86.RCLL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCLL instruction to the active function. +// Operates on the global context. +func RCLL(ci, mr operand.Op) { ctx.RCLL(ci, mr) } + +// 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 +// Construct and append a RCLQ instruction to the active function. +func (c *Context) RCLQ(ci, mr operand.Op) { + if inst, err := x86.RCLQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCLQ instruction to the active function. +// Operates on the global context. +func RCLQ(ci, mr operand.Op) { ctx.RCLQ(ci, mr) } + +// 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 +// Construct and append a RCLW instruction to the active function. +func (c *Context) RCLW(ci, mr operand.Op) { + if inst, err := x86.RCLW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCLW instruction to the active function. +// Operates on the global context. +func RCLW(ci, mr operand.Op) { ctx.RCLW(ci, mr) } + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +// Construct and append a RCPPS instruction to the active function. +func (c *Context) RCPPS(mx, x operand.Op) { + if inst, err := x86.RCPPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +// Construct and append a RCPPS instruction to the active function. +// Operates on the global context. +func RCPPS(mx, x operand.Op) { ctx.RCPPS(mx, x) } + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +// Construct and append a RCPSS instruction to the active function. +func (c *Context) RCPSS(mx, x operand.Op) { + if inst, err := x86.RCPSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +// Construct and append a RCPSS instruction to the active function. +// Operates on the global context. +func RCPSS(mx, x operand.Op) { ctx.RCPSS(mx, x) } + +// 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 +// Construct and append a RCRB instruction to the active function. +func (c *Context) RCRB(ci, mr operand.Op) { + if inst, err := x86.RCRB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCRB instruction to the active function. +// Operates on the global context. +func RCRB(ci, mr operand.Op) { ctx.RCRB(ci, mr) } + +// 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 +// Construct and append a RCRL instruction to the active function. +func (c *Context) RCRL(ci, mr operand.Op) { + if inst, err := x86.RCRL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCRL instruction to the active function. +// Operates on the global context. +func RCRL(ci, mr operand.Op) { ctx.RCRL(ci, mr) } + +// 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 +// Construct and append a RCRQ instruction to the active function. +func (c *Context) RCRQ(ci, mr operand.Op) { + if inst, err := x86.RCRQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCRQ instruction to the active function. +// Operates on the global context. +func RCRQ(ci, mr operand.Op) { ctx.RCRQ(ci, mr) } + +// 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 +// Construct and append a RCRW instruction to the active function. +func (c *Context) RCRW(ci, mr operand.Op) { + if inst, err := x86.RCRW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a RCRW instruction to the active function. +// Operates on the global context. +func RCRW(ci, mr operand.Op) { ctx.RCRW(ci, mr) } + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +// Construct and append a RDRANDL instruction to the active function. +func (c *Context) RDRANDL(r operand.Op) { + if inst, err := x86.RDRANDL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +// Construct and append a RDRANDL instruction to the active function. +// Operates on the global context. +func RDRANDL(r operand.Op) { ctx.RDRANDL(r) } + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +// Construct and append a RDRANDQ instruction to the active function. +func (c *Context) RDRANDQ(r operand.Op) { + if inst, err := x86.RDRANDQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +// Construct and append a RDRANDQ instruction to the active function. +// Operates on the global context. +func RDRANDQ(r operand.Op) { ctx.RDRANDQ(r) } + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +// Construct and append a RDRANDW instruction to the active function. +func (c *Context) RDRANDW(r operand.Op) { + if inst, err := x86.RDRANDW(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +// Construct and append a RDRANDW instruction to the active function. +// Operates on the global context. +func RDRANDW(r operand.Op) { ctx.RDRANDW(r) } + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +// Construct and append a RDSEEDL instruction to the active function. +func (c *Context) RDSEEDL(r operand.Op) { + if inst, err := x86.RDSEEDL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +// Construct and append a RDSEEDL instruction to the active function. +// Operates on the global context. +func RDSEEDL(r operand.Op) { ctx.RDSEEDL(r) } + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +// Construct and append a RDSEEDQ instruction to the active function. +func (c *Context) RDSEEDQ(r operand.Op) { + if inst, err := x86.RDSEEDQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +// Construct and append a RDSEEDQ instruction to the active function. +// Operates on the global context. +func RDSEEDQ(r operand.Op) { ctx.RDSEEDQ(r) } + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +// Construct and append a RDSEEDW instruction to the active function. +func (c *Context) RDSEEDW(r operand.Op) { + if inst, err := x86.RDSEEDW(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +// Construct and append a RDSEEDW instruction to the active function. +// Operates on the global context. +func RDSEEDW(r operand.Op) { ctx.RDSEEDW(r) } + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +// Construct and append a RDTSC instruction to the active function. +func (c *Context) RDTSC() { + if inst, err := x86.RDTSC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +// Construct and append a RDTSC instruction to the active function. +// Operates on the global context. +func RDTSC() { ctx.RDTSC() } + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +// Construct and append a RDTSCP instruction to the active function. +func (c *Context) RDTSCP() { + if inst, err := x86.RDTSCP(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +// Construct and append a RDTSCP instruction to the active function. +// Operates on the global context. +func RDTSCP() { ctx.RDTSCP() } + +// RET: Return from Procedure. +// +// Forms: +// +// RET +// Construct and append a RET instruction to the active function. +func (c *Context) RET() { + if inst, err := x86.RET(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RET: Return from Procedure. +// +// Forms: +// +// RET +// Construct and append a RET instruction to the active function. +// Operates on the global context. +func RET() { ctx.RET() } + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +// Construct and append a RETFL instruction to the active function. +func (c *Context) RETFL(i operand.Op) { + if inst, err := x86.RETFL(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +// Construct and append a RETFL instruction to the active function. +// Operates on the global context. +func RETFL(i operand.Op) { ctx.RETFL(i) } + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +// Construct and append a RETFQ instruction to the active function. +func (c *Context) RETFQ(i operand.Op) { + if inst, err := x86.RETFQ(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +// Construct and append a RETFQ instruction to the active function. +// Operates on the global context. +func RETFQ(i operand.Op) { ctx.RETFQ(i) } + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +// Construct and append a RETFW instruction to the active function. +func (c *Context) RETFW(i operand.Op) { + if inst, err := x86.RETFW(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +// Construct and append a RETFW instruction to the active function. +// Operates on the global context. +func RETFW(i operand.Op) { ctx.RETFW(i) } + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +// Construct and append a ROLB instruction to the active function. +func (c *Context) ROLB(ci, mr operand.Op) { + if inst, err := x86.ROLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +// Construct and append a ROLB instruction to the active function. +// Operates on the global context. +func ROLB(ci, mr operand.Op) { ctx.ROLB(ci, mr) } + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +// Construct and append a ROLL instruction to the active function. +func (c *Context) ROLL(ci, mr operand.Op) { + if inst, err := x86.ROLL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +// Construct and append a ROLL instruction to the active function. +// Operates on the global context. +func ROLL(ci, mr operand.Op) { ctx.ROLL(ci, mr) } + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +// Construct and append a ROLQ instruction to the active function. +func (c *Context) ROLQ(ci, mr operand.Op) { + if inst, err := x86.ROLQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +// Construct and append a ROLQ instruction to the active function. +// Operates on the global context. +func ROLQ(ci, mr operand.Op) { ctx.ROLQ(ci, mr) } + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +// Construct and append a ROLW instruction to the active function. +func (c *Context) ROLW(ci, mr operand.Op) { + if inst, err := x86.ROLW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +// Construct and append a ROLW instruction to the active function. +// Operates on the global context. +func ROLW(ci, mr operand.Op) { ctx.ROLW(ci, mr) } + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +// Construct and append a RORB instruction to the active function. +func (c *Context) RORB(ci, mr operand.Op) { + if inst, err := x86.RORB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +// Construct and append a RORB instruction to the active function. +// Operates on the global context. +func RORB(ci, mr operand.Op) { ctx.RORB(ci, mr) } + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +// Construct and append a RORL instruction to the active function. +func (c *Context) RORL(ci, mr operand.Op) { + if inst, err := x86.RORL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +// Construct and append a RORL instruction to the active function. +// Operates on the global context. +func RORL(ci, mr operand.Op) { ctx.RORL(ci, mr) } + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +// Construct and append a RORQ instruction to the active function. +func (c *Context) RORQ(ci, mr operand.Op) { + if inst, err := x86.RORQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +// Construct and append a RORQ instruction to the active function. +// Operates on the global context. +func RORQ(ci, mr operand.Op) { ctx.RORQ(ci, mr) } + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +// Construct and append a RORW instruction to the active function. +func (c *Context) RORW(ci, mr operand.Op) { + if inst, err := x86.RORW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +// Construct and append a RORW instruction to the active function. +// Operates on the global context. +func RORW(ci, mr operand.Op) { ctx.RORW(ci, mr) } + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +// Construct and append a RORXL instruction to the active function. +func (c *Context) RORXL(i, mr, r operand.Op) { + if inst, err := x86.RORXL(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +// Construct and append a RORXL instruction to the active function. +// Operates on the global context. +func RORXL(i, mr, r operand.Op) { ctx.RORXL(i, mr, r) } + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +// Construct and append a RORXQ instruction to the active function. +func (c *Context) RORXQ(i, mr, r operand.Op) { + if inst, err := x86.RORXQ(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +// Construct and append a RORXQ instruction to the active function. +// Operates on the global context. +func RORXQ(i, mr, r operand.Op) { ctx.RORXQ(i, mr, r) } + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +// Construct and append a ROUNDPD instruction to the active function. +func (c *Context) ROUNDPD(i, mx, x operand.Op) { + if inst, err := x86.ROUNDPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +// Construct and append a ROUNDPD instruction to the active function. +// Operates on the global context. +func ROUNDPD(i, mx, x operand.Op) { ctx.ROUNDPD(i, mx, x) } + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +// Construct and append a ROUNDPS instruction to the active function. +func (c *Context) ROUNDPS(i, mx, x operand.Op) { + if inst, err := x86.ROUNDPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +// Construct and append a ROUNDPS instruction to the active function. +// Operates on the global context. +func ROUNDPS(i, mx, x operand.Op) { ctx.ROUNDPS(i, mx, x) } + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +// Construct and append a ROUNDSD instruction to the active function. +func (c *Context) ROUNDSD(i, mx, x operand.Op) { + if inst, err := x86.ROUNDSD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +// Construct and append a ROUNDSD instruction to the active function. +// Operates on the global context. +func ROUNDSD(i, mx, x operand.Op) { ctx.ROUNDSD(i, mx, x) } + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +// Construct and append a ROUNDSS instruction to the active function. +func (c *Context) ROUNDSS(i, mx, x operand.Op) { + if inst, err := x86.ROUNDSS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +// Construct and append a ROUNDSS instruction to the active function. +// Operates on the global context. +func ROUNDSS(i, mx, x operand.Op) { ctx.ROUNDSS(i, mx, x) } + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +// Construct and append a RSQRTPS instruction to the active function. +func (c *Context) RSQRTPS(mx, x operand.Op) { + if inst, err := x86.RSQRTPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +// Construct and append a RSQRTPS instruction to the active function. +// Operates on the global context. +func RSQRTPS(mx, x operand.Op) { ctx.RSQRTPS(mx, x) } + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +// Construct and append a RSQRTSS instruction to the active function. +func (c *Context) RSQRTSS(mx, x operand.Op) { + if inst, err := x86.RSQRTSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +// Construct and append a RSQRTSS instruction to the active function. +// Operates on the global context. +func RSQRTSS(mx, x operand.Op) { ctx.RSQRTSS(mx, x) } + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +// Construct and append a SALB instruction to the active function. +func (c *Context) SALB(ci, mr operand.Op) { + if inst, err := x86.SALB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +// Construct and append a SALB instruction to the active function. +// Operates on the global context. +func SALB(ci, mr operand.Op) { ctx.SALB(ci, mr) } + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +// Construct and append a SALL instruction to the active function. +func (c *Context) SALL(ci, mr operand.Op) { + if inst, err := x86.SALL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +// Construct and append a SALL instruction to the active function. +// Operates on the global context. +func SALL(ci, mr operand.Op) { ctx.SALL(ci, mr) } + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +// Construct and append a SALQ instruction to the active function. +func (c *Context) SALQ(ci, mr operand.Op) { + if inst, err := x86.SALQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +// Construct and append a SALQ instruction to the active function. +// Operates on the global context. +func SALQ(ci, mr operand.Op) { ctx.SALQ(ci, mr) } + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +// Construct and append a SALW instruction to the active function. +func (c *Context) SALW(ci, mr operand.Op) { + if inst, err := x86.SALW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +// Construct and append a SALW instruction to the active function. +// Operates on the global context. +func SALW(ci, mr operand.Op) { ctx.SALW(ci, mr) } + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +// Construct and append a SARB instruction to the active function. +func (c *Context) SARB(ci, mr operand.Op) { + if inst, err := x86.SARB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +// Construct and append a SARB instruction to the active function. +// Operates on the global context. +func SARB(ci, mr operand.Op) { ctx.SARB(ci, mr) } + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +// Construct and append a SARL instruction to the active function. +func (c *Context) SARL(ci, mr operand.Op) { + if inst, err := x86.SARL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +// Construct and append a SARL instruction to the active function. +// Operates on the global context. +func SARL(ci, mr operand.Op) { ctx.SARL(ci, mr) } + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +// Construct and append a SARQ instruction to the active function. +func (c *Context) SARQ(ci, mr operand.Op) { + if inst, err := x86.SARQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +// Construct and append a SARQ instruction to the active function. +// Operates on the global context. +func SARQ(ci, mr operand.Op) { ctx.SARQ(ci, mr) } + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +// Construct and append a SARW instruction to the active function. +func (c *Context) SARW(ci, mr operand.Op) { + if inst, err := x86.SARW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +// Construct and append a SARW instruction to the active function. +// Operates on the global context. +func SARW(ci, mr operand.Op) { ctx.SARW(ci, mr) } + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +// Construct and append a SARXL instruction to the active function. +func (c *Context) SARXL(r, mr, r1 operand.Op) { + if inst, err := x86.SARXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +// Construct and append a SARXL instruction to the active function. +// Operates on the global context. +func SARXL(r, mr, r1 operand.Op) { ctx.SARXL(r, mr, r1) } + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +// Construct and append a SARXQ instruction to the active function. +func (c *Context) SARXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SARXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +// Construct and append a SARXQ instruction to the active function. +// Operates on the global context. +func SARXQ(r, mr, r1 operand.Op) { ctx.SARXQ(r, mr, r1) } + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +// Construct and append a SBBB instruction to the active function. +func (c *Context) SBBB(imr, amr operand.Op) { + if inst, err := x86.SBBB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +// Construct and append a SBBB instruction to the active function. +// Operates on the global context. +func SBBB(imr, amr operand.Op) { ctx.SBBB(imr, amr) } + +// 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 +// Construct and append a SBBL instruction to the active function. +func (c *Context) SBBL(imr, emr operand.Op) { + if inst, err := x86.SBBL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SBBL instruction to the active function. +// Operates on the global context. +func SBBL(imr, emr operand.Op) { ctx.SBBL(imr, emr) } + +// 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 +// Construct and append a SBBQ instruction to the active function. +func (c *Context) SBBQ(imr, mr operand.Op) { + if inst, err := x86.SBBQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SBBQ instruction to the active function. +// Operates on the global context. +func SBBQ(imr, mr operand.Op) { ctx.SBBQ(imr, mr) } + +// 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 +// Construct and append a SBBW instruction to the active function. +func (c *Context) SBBW(imr, amr operand.Op) { + if inst, err := x86.SBBW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SBBW instruction to the active function. +// Operates on the global context. +func SBBW(imr, amr operand.Op) { ctx.SBBW(imr, amr) } + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +// Construct and append a SETCC instruction to the active function. +func (c *Context) SETCC(mr operand.Op) { + if inst, err := x86.SETCC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +// Construct and append a SETCC instruction to the active function. +// Operates on the global context. +func SETCC(mr operand.Op) { ctx.SETCC(mr) } + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +// Construct and append a SETCS instruction to the active function. +func (c *Context) SETCS(mr operand.Op) { + if inst, err := x86.SETCS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +// Construct and append a SETCS instruction to the active function. +// Operates on the global context. +func SETCS(mr operand.Op) { ctx.SETCS(mr) } + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +// Construct and append a SETEQ instruction to the active function. +func (c *Context) SETEQ(mr operand.Op) { + if inst, err := x86.SETEQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +// Construct and append a SETEQ instruction to the active function. +// Operates on the global context. +func SETEQ(mr operand.Op) { ctx.SETEQ(mr) } + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +// Construct and append a SETGE instruction to the active function. +func (c *Context) SETGE(mr operand.Op) { + if inst, err := x86.SETGE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +// Construct and append a SETGE instruction to the active function. +// Operates on the global context. +func SETGE(mr operand.Op) { ctx.SETGE(mr) } + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +// Construct and append a SETGT instruction to the active function. +func (c *Context) SETGT(mr operand.Op) { + if inst, err := x86.SETGT(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +// Construct and append a SETGT instruction to the active function. +// Operates on the global context. +func SETGT(mr operand.Op) { ctx.SETGT(mr) } + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +// Construct and append a SETHI instruction to the active function. +func (c *Context) SETHI(mr operand.Op) { + if inst, err := x86.SETHI(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +// Construct and append a SETHI instruction to the active function. +// Operates on the global context. +func SETHI(mr operand.Op) { ctx.SETHI(mr) } + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +// Construct and append a SETLE instruction to the active function. +func (c *Context) SETLE(mr operand.Op) { + if inst, err := x86.SETLE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +// Construct and append a SETLE instruction to the active function. +// Operates on the global context. +func SETLE(mr operand.Op) { ctx.SETLE(mr) } + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +// Construct and append a SETLS instruction to the active function. +func (c *Context) SETLS(mr operand.Op) { + if inst, err := x86.SETLS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +// Construct and append a SETLS instruction to the active function. +// Operates on the global context. +func SETLS(mr operand.Op) { ctx.SETLS(mr) } + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +// Construct and append a SETLT instruction to the active function. +func (c *Context) SETLT(mr operand.Op) { + if inst, err := x86.SETLT(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +// Construct and append a SETLT instruction to the active function. +// Operates on the global context. +func SETLT(mr operand.Op) { ctx.SETLT(mr) } + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +// Construct and append a SETMI instruction to the active function. +func (c *Context) SETMI(mr operand.Op) { + if inst, err := x86.SETMI(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +// Construct and append a SETMI instruction to the active function. +// Operates on the global context. +func SETMI(mr operand.Op) { ctx.SETMI(mr) } + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +// Construct and append a SETNE instruction to the active function. +func (c *Context) SETNE(mr operand.Op) { + if inst, err := x86.SETNE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +// Construct and append a SETNE instruction to the active function. +// Operates on the global context. +func SETNE(mr operand.Op) { ctx.SETNE(mr) } + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +// Construct and append a SETOC instruction to the active function. +func (c *Context) SETOC(mr operand.Op) { + if inst, err := x86.SETOC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +// Construct and append a SETOC instruction to the active function. +// Operates on the global context. +func SETOC(mr operand.Op) { ctx.SETOC(mr) } + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +// Construct and append a SETOS instruction to the active function. +func (c *Context) SETOS(mr operand.Op) { + if inst, err := x86.SETOS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +// Construct and append a SETOS instruction to the active function. +// Operates on the global context. +func SETOS(mr operand.Op) { ctx.SETOS(mr) } + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +// Construct and append a SETPC instruction to the active function. +func (c *Context) SETPC(mr operand.Op) { + if inst, err := x86.SETPC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +// Construct and append a SETPC instruction to the active function. +// Operates on the global context. +func SETPC(mr operand.Op) { ctx.SETPC(mr) } + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +// Construct and append a SETPL instruction to the active function. +func (c *Context) SETPL(mr operand.Op) { + if inst, err := x86.SETPL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +// Construct and append a SETPL instruction to the active function. +// Operates on the global context. +func SETPL(mr operand.Op) { ctx.SETPL(mr) } + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +// Construct and append a SETPS instruction to the active function. +func (c *Context) SETPS(mr operand.Op) { + if inst, err := x86.SETPS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +// Construct and append a SETPS instruction to the active function. +// Operates on the global context. +func SETPS(mr operand.Op) { ctx.SETPS(mr) } + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +// Construct and append a SFENCE instruction to the active function. +func (c *Context) SFENCE() { + if inst, err := x86.SFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +// Construct and append a SFENCE instruction to the active function. +// Operates on the global context. +func SFENCE() { ctx.SFENCE() } + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +// Construct and append a SHA1MSG1 instruction to the active function. +func (c *Context) SHA1MSG1(mx, x operand.Op) { + if inst, err := x86.SHA1MSG1(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +// Construct and append a SHA1MSG1 instruction to the active function. +// Operates on the global context. +func SHA1MSG1(mx, x operand.Op) { ctx.SHA1MSG1(mx, x) } + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +// Construct and append a SHA1MSG2 instruction to the active function. +func (c *Context) SHA1MSG2(mx, x operand.Op) { + if inst, err := x86.SHA1MSG2(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +// Construct and append a SHA1MSG2 instruction to the active function. +// Operates on the global context. +func SHA1MSG2(mx, x operand.Op) { ctx.SHA1MSG2(mx, x) } + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +// Construct and append a SHA1NEXTE instruction to the active function. +func (c *Context) SHA1NEXTE(mx, x operand.Op) { + if inst, err := x86.SHA1NEXTE(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +// Construct and append a SHA1NEXTE instruction to the active function. +// Operates on the global context. +func SHA1NEXTE(mx, x operand.Op) { ctx.SHA1NEXTE(mx, x) } + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +// Construct and append a SHA1RNDS4 instruction to the active function. +func (c *Context) SHA1RNDS4(i, mx, x operand.Op) { + if inst, err := x86.SHA1RNDS4(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +// Construct and append a SHA1RNDS4 instruction to the active function. +// Operates on the global context. +func SHA1RNDS4(i, mx, x operand.Op) { ctx.SHA1RNDS4(i, mx, x) } + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +// Construct and append a SHA256MSG1 instruction to the active function. +func (c *Context) SHA256MSG1(mx, x operand.Op) { + if inst, err := x86.SHA256MSG1(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +// Construct and append a SHA256MSG1 instruction to the active function. +// Operates on the global context. +func SHA256MSG1(mx, x operand.Op) { ctx.SHA256MSG1(mx, x) } + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +// Construct and append a SHA256MSG2 instruction to the active function. +func (c *Context) SHA256MSG2(mx, x operand.Op) { + if inst, err := x86.SHA256MSG2(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +// Construct and append a SHA256MSG2 instruction to the active function. +// Operates on the global context. +func SHA256MSG2(mx, x operand.Op) { ctx.SHA256MSG2(mx, x) } + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +// Construct and append a SHA256RNDS2 instruction to the active function. +func (c *Context) SHA256RNDS2(x, mx, x1 operand.Op) { + if inst, err := x86.SHA256RNDS2(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +// Construct and append a SHA256RNDS2 instruction to the active function. +// Operates on the global context. +func SHA256RNDS2(x, mx, x1 operand.Op) { ctx.SHA256RNDS2(x, mx, x1) } + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +// Construct and append a SHLB instruction to the active function. +func (c *Context) SHLB(ci, mr operand.Op) { + if inst, err := x86.SHLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +// Construct and append a SHLB instruction to the active function. +// Operates on the global context. +func SHLB(ci, mr operand.Op) { ctx.SHLB(ci, mr) } + +// 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 +// Construct and append a SHLL instruction to the active function. +func (c *Context) SHLL(ops ...operand.Op) { + if inst, err := x86.SHLL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHLL instruction to the active function. +// Operates on the global context. +func SHLL(ops ...operand.Op) { ctx.SHLL(ops...) } + +// 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 +// Construct and append a SHLQ instruction to the active function. +func (c *Context) SHLQ(ops ...operand.Op) { + if inst, err := x86.SHLQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHLQ instruction to the active function. +// Operates on the global context. +func SHLQ(ops ...operand.Op) { ctx.SHLQ(ops...) } + +// 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 +// Construct and append a SHLW instruction to the active function. +func (c *Context) SHLW(ops ...operand.Op) { + if inst, err := x86.SHLW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHLW instruction to the active function. +// Operates on the global context. +func SHLW(ops ...operand.Op) { ctx.SHLW(ops...) } + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +// Construct and append a SHLXL instruction to the active function. +func (c *Context) SHLXL(r, mr, r1 operand.Op) { + if inst, err := x86.SHLXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +// Construct and append a SHLXL instruction to the active function. +// Operates on the global context. +func SHLXL(r, mr, r1 operand.Op) { ctx.SHLXL(r, mr, r1) } + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +// Construct and append a SHLXQ instruction to the active function. +func (c *Context) SHLXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SHLXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +// Construct and append a SHLXQ instruction to the active function. +// Operates on the global context. +func SHLXQ(r, mr, r1 operand.Op) { ctx.SHLXQ(r, mr, r1) } + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +// Construct and append a SHRB instruction to the active function. +func (c *Context) SHRB(ci, mr operand.Op) { + if inst, err := x86.SHRB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +// Construct and append a SHRB instruction to the active function. +// Operates on the global context. +func SHRB(ci, mr operand.Op) { ctx.SHRB(ci, mr) } + +// 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 +// Construct and append a SHRL instruction to the active function. +func (c *Context) SHRL(ops ...operand.Op) { + if inst, err := x86.SHRL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHRL instruction to the active function. +// Operates on the global context. +func SHRL(ops ...operand.Op) { ctx.SHRL(ops...) } + +// 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 +// Construct and append a SHRQ instruction to the active function. +func (c *Context) SHRQ(ops ...operand.Op) { + if inst, err := x86.SHRQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHRQ instruction to the active function. +// Operates on the global context. +func SHRQ(ops ...operand.Op) { ctx.SHRQ(ops...) } + +// 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 +// Construct and append a SHRW instruction to the active function. +func (c *Context) SHRW(ops ...operand.Op) { + if inst, err := x86.SHRW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SHRW instruction to the active function. +// Operates on the global context. +func SHRW(ops ...operand.Op) { ctx.SHRW(ops...) } + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +// Construct and append a SHRXL instruction to the active function. +func (c *Context) SHRXL(r, mr, r1 operand.Op) { + if inst, err := x86.SHRXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +// Construct and append a SHRXL instruction to the active function. +// Operates on the global context. +func SHRXL(r, mr, r1 operand.Op) { ctx.SHRXL(r, mr, r1) } + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +// Construct and append a SHRXQ instruction to the active function. +func (c *Context) SHRXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SHRXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +// Construct and append a SHRXQ instruction to the active function. +// Operates on the global context. +func SHRXQ(r, mr, r1 operand.Op) { ctx.SHRXQ(r, mr, r1) } + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +// Construct and append a SHUFPD instruction to the active function. +func (c *Context) SHUFPD(i, mx, x operand.Op) { + if inst, err := x86.SHUFPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +// Construct and append a SHUFPD instruction to the active function. +// Operates on the global context. +func SHUFPD(i, mx, x operand.Op) { ctx.SHUFPD(i, mx, x) } + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +// Construct and append a SHUFPS instruction to the active function. +func (c *Context) SHUFPS(i, mx, x operand.Op) { + if inst, err := x86.SHUFPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +// Construct and append a SHUFPS instruction to the active function. +// Operates on the global context. +func SHUFPS(i, mx, x operand.Op) { ctx.SHUFPS(i, mx, x) } + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +// Construct and append a SQRTPD instruction to the active function. +func (c *Context) SQRTPD(mx, x operand.Op) { + if inst, err := x86.SQRTPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +// Construct and append a SQRTPD instruction to the active function. +// Operates on the global context. +func SQRTPD(mx, x operand.Op) { ctx.SQRTPD(mx, x) } + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +// Construct and append a SQRTPS instruction to the active function. +func (c *Context) SQRTPS(mx, x operand.Op) { + if inst, err := x86.SQRTPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +// Construct and append a SQRTPS instruction to the active function. +// Operates on the global context. +func SQRTPS(mx, x operand.Op) { ctx.SQRTPS(mx, x) } + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +// Construct and append a SQRTSD instruction to the active function. +func (c *Context) SQRTSD(mx, x operand.Op) { + if inst, err := x86.SQRTSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +// Construct and append a SQRTSD instruction to the active function. +// Operates on the global context. +func SQRTSD(mx, x operand.Op) { ctx.SQRTSD(mx, x) } + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +// Construct and append a SQRTSS instruction to the active function. +func (c *Context) SQRTSS(mx, x operand.Op) { + if inst, err := x86.SQRTSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +// Construct and append a SQRTSS instruction to the active function. +// Operates on the global context. +func SQRTSS(mx, x operand.Op) { ctx.SQRTSS(mx, x) } + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +// Construct and append a STC instruction to the active function. +func (c *Context) STC() { + if inst, err := x86.STC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +// Construct and append a STC instruction to the active function. +// Operates on the global context. +func STC() { ctx.STC() } + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +// Construct and append a STD instruction to the active function. +func (c *Context) STD() { + if inst, err := x86.STD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +// Construct and append a STD instruction to the active function. +// Operates on the global context. +func STD() { ctx.STD() } + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +// Construct and append a STMXCSR instruction to the active function. +func (c *Context) STMXCSR(m operand.Op) { + if inst, err := x86.STMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +// Construct and append a STMXCSR instruction to the active function. +// Operates on the global context. +func STMXCSR(m operand.Op) { ctx.STMXCSR(m) } + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +// Construct and append a SUBB instruction to the active function. +func (c *Context) SUBB(imr, amr operand.Op) { + if inst, err := x86.SUBB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +// Construct and append a SUBB instruction to the active function. +// Operates on the global context. +func SUBB(imr, amr operand.Op) { ctx.SUBB(imr, amr) } + +// 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 +// Construct and append a SUBL instruction to the active function. +func (c *Context) SUBL(imr, emr operand.Op) { + if inst, err := x86.SUBL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SUBL instruction to the active function. +// Operates on the global context. +func SUBL(imr, emr operand.Op) { ctx.SUBL(imr, emr) } + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +// Construct and append a SUBPD instruction to the active function. +func (c *Context) SUBPD(mx, x operand.Op) { + if inst, err := x86.SUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +// Construct and append a SUBPD instruction to the active function. +// Operates on the global context. +func SUBPD(mx, x operand.Op) { ctx.SUBPD(mx, x) } + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +// Construct and append a SUBPS instruction to the active function. +func (c *Context) SUBPS(mx, x operand.Op) { + if inst, err := x86.SUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +// Construct and append a SUBPS instruction to the active function. +// Operates on the global context. +func SUBPS(mx, x operand.Op) { ctx.SUBPS(mx, x) } + +// 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 +// Construct and append a SUBQ instruction to the active function. +func (c *Context) SUBQ(imr, mr operand.Op) { + if inst, err := x86.SUBQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SUBQ instruction to the active function. +// Operates on the global context. +func SUBQ(imr, mr operand.Op) { ctx.SUBQ(imr, mr) } + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +// Construct and append a SUBSD instruction to the active function. +func (c *Context) SUBSD(mx, x operand.Op) { + if inst, err := x86.SUBSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +// Construct and append a SUBSD instruction to the active function. +// Operates on the global context. +func SUBSD(mx, x operand.Op) { ctx.SUBSD(mx, x) } + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +// Construct and append a SUBSS instruction to the active function. +func (c *Context) SUBSS(mx, x operand.Op) { + if inst, err := x86.SUBSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +// Construct and append a SUBSS instruction to the active function. +// Operates on the global context. +func SUBSS(mx, x operand.Op) { ctx.SUBSS(mx, x) } + +// 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 +// Construct and append a SUBW instruction to the active function. +func (c *Context) SUBW(imr, amr operand.Op) { + if inst, err := x86.SUBW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a SUBW instruction to the active function. +// Operates on the global context. +func SUBW(imr, amr operand.Op) { ctx.SUBW(imr, amr) } + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +// Construct and append a SYSCALL instruction to the active function. +func (c *Context) SYSCALL() { + if inst, err := x86.SYSCALL(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +// Construct and append a SYSCALL instruction to the active function. +// Operates on the global context. +func SYSCALL() { ctx.SYSCALL() } + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +// Construct and append a TESTB instruction to the active function. +func (c *Context) TESTB(ir, amr operand.Op) { + if inst, err := x86.TESTB(ir, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +// Construct and append a TESTB instruction to the active function. +// Operates on the global context. +func TESTB(ir, amr operand.Op) { ctx.TESTB(ir, amr) } + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +// Construct and append a TESTL instruction to the active function. +func (c *Context) TESTL(ir, emr operand.Op) { + if inst, err := x86.TESTL(ir, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +// Construct and append a TESTL instruction to the active function. +// Operates on the global context. +func TESTL(ir, emr operand.Op) { ctx.TESTL(ir, emr) } + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +// Construct and append a TESTQ instruction to the active function. +func (c *Context) TESTQ(ir, mr operand.Op) { + if inst, err := x86.TESTQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +// Construct and append a TESTQ instruction to the active function. +// Operates on the global context. +func TESTQ(ir, mr operand.Op) { ctx.TESTQ(ir, mr) } + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +// Construct and append a TESTW instruction to the active function. +func (c *Context) TESTW(ir, amr operand.Op) { + if inst, err := x86.TESTW(ir, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +// Construct and append a TESTW instruction to the active function. +// Operates on the global context. +func TESTW(ir, amr operand.Op) { ctx.TESTW(ir, amr) } + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +// Construct and append a TZCNTL instruction to the active function. +func (c *Context) TZCNTL(mr, r operand.Op) { + if inst, err := x86.TZCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +// Construct and append a TZCNTL instruction to the active function. +// Operates on the global context. +func TZCNTL(mr, r operand.Op) { ctx.TZCNTL(mr, r) } + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +// Construct and append a TZCNTQ instruction to the active function. +func (c *Context) TZCNTQ(mr, r operand.Op) { + if inst, err := x86.TZCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +// Construct and append a TZCNTQ instruction to the active function. +// Operates on the global context. +func TZCNTQ(mr, r operand.Op) { ctx.TZCNTQ(mr, r) } + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +// Construct and append a TZCNTW instruction to the active function. +func (c *Context) TZCNTW(mr, r operand.Op) { + if inst, err := x86.TZCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +// Construct and append a TZCNTW instruction to the active function. +// Operates on the global context. +func TZCNTW(mr, r operand.Op) { ctx.TZCNTW(mr, r) } + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +// Construct and append a UCOMISD instruction to the active function. +func (c *Context) UCOMISD(mx, x operand.Op) { + if inst, err := x86.UCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +// Construct and append a UCOMISD instruction to the active function. +// Operates on the global context. +func UCOMISD(mx, x operand.Op) { ctx.UCOMISD(mx, x) } + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +// Construct and append a UCOMISS instruction to the active function. +func (c *Context) UCOMISS(mx, x operand.Op) { + if inst, err := x86.UCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +// Construct and append a UCOMISS instruction to the active function. +// Operates on the global context. +func UCOMISS(mx, x operand.Op) { ctx.UCOMISS(mx, x) } + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +// Construct and append a UD2 instruction to the active function. +func (c *Context) UD2() { + if inst, err := x86.UD2(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +// Construct and append a UD2 instruction to the active function. +// Operates on the global context. +func UD2() { ctx.UD2() } + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +// Construct and append a UNPCKHPD instruction to the active function. +func (c *Context) UNPCKHPD(mx, x operand.Op) { + if inst, err := x86.UNPCKHPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +// Construct and append a UNPCKHPD instruction to the active function. +// Operates on the global context. +func UNPCKHPD(mx, x operand.Op) { ctx.UNPCKHPD(mx, x) } + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +// Construct and append a UNPCKHPS instruction to the active function. +func (c *Context) UNPCKHPS(mx, x operand.Op) { + if inst, err := x86.UNPCKHPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +// Construct and append a UNPCKHPS instruction to the active function. +// Operates on the global context. +func UNPCKHPS(mx, x operand.Op) { ctx.UNPCKHPS(mx, x) } + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +// Construct and append a UNPCKLPD instruction to the active function. +func (c *Context) UNPCKLPD(mx, x operand.Op) { + if inst, err := x86.UNPCKLPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +// Construct and append a UNPCKLPD instruction to the active function. +// Operates on the global context. +func UNPCKLPD(mx, x operand.Op) { ctx.UNPCKLPD(mx, x) } + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +// Construct and append a UNPCKLPS instruction to the active function. +func (c *Context) UNPCKLPS(mx, x operand.Op) { + if inst, err := x86.UNPCKLPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +// Construct and append a UNPCKLPS instruction to the active function. +// Operates on the global context. +func UNPCKLPS(mx, x operand.Op) { ctx.UNPCKLPS(mx, x) } + +// 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 +// Construct and append a VADDPD instruction to the active function. +func (c *Context) VADDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VADDPD instruction to the active function. +// Operates on the global context. +func VADDPD(mxy, xy, xy1 operand.Op) { ctx.VADDPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VADDPS instruction to the active function. +func (c *Context) VADDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VADDPS instruction to the active function. +// Operates on the global context. +func VADDPS(mxy, xy, xy1 operand.Op) { ctx.VADDPS(mxy, xy, xy1) } + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +// Construct and append a VADDSD instruction to the active function. +func (c *Context) VADDSD(mx, x, x1 operand.Op) { + if inst, err := x86.VADDSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +// Construct and append a VADDSD instruction to the active function. +// Operates on the global context. +func VADDSD(mx, x, x1 operand.Op) { ctx.VADDSD(mx, x, x1) } + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +// Construct and append a VADDSS instruction to the active function. +func (c *Context) VADDSS(mx, x, x1 operand.Op) { + if inst, err := x86.VADDSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +// Construct and append a VADDSS instruction to the active function. +// Operates on the global context. +func VADDSS(mx, x, x1 operand.Op) { ctx.VADDSS(mx, x, x1) } + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +// Construct and append a VADDSUBPD instruction to the active function. +func (c *Context) VADDSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +// Construct and append a VADDSUBPD instruction to the active function. +// Operates on the global context. +func VADDSUBPD(mxy, xy, xy1 operand.Op) { ctx.VADDSUBPD(mxy, xy, xy1) } + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +// Construct and append a VADDSUBPS instruction to the active function. +func (c *Context) VADDSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +// Construct and append a VADDSUBPS instruction to the active function. +// Operates on the global context. +func VADDSUBPS(mxy, xy, xy1 operand.Op) { ctx.VADDSUBPS(mxy, xy, xy1) } + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +// Construct and append a VAESDEC instruction to the active function. +func (c *Context) VAESDEC(mx, x, x1 operand.Op) { + if inst, err := x86.VAESDEC(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +// Construct and append a VAESDEC instruction to the active function. +// Operates on the global context. +func VAESDEC(mx, x, x1 operand.Op) { ctx.VAESDEC(mx, x, x1) } + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +// Construct and append a VAESDECLAST instruction to the active function. +func (c *Context) VAESDECLAST(mx, x, x1 operand.Op) { + if inst, err := x86.VAESDECLAST(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +// Construct and append a VAESDECLAST instruction to the active function. +// Operates on the global context. +func VAESDECLAST(mx, x, x1 operand.Op) { ctx.VAESDECLAST(mx, x, x1) } + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +// Construct and append a VAESENC instruction to the active function. +func (c *Context) VAESENC(mx, x, x1 operand.Op) { + if inst, err := x86.VAESENC(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +// Construct and append a VAESENC instruction to the active function. +// Operates on the global context. +func VAESENC(mx, x, x1 operand.Op) { ctx.VAESENC(mx, x, x1) } + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +// Construct and append a VAESENCLAST instruction to the active function. +func (c *Context) VAESENCLAST(mx, x, x1 operand.Op) { + if inst, err := x86.VAESENCLAST(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +// Construct and append a VAESENCLAST instruction to the active function. +// Operates on the global context. +func VAESENCLAST(mx, x, x1 operand.Op) { ctx.VAESENCLAST(mx, x, x1) } + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +// Construct and append a VAESIMC instruction to the active function. +func (c *Context) VAESIMC(mx, x operand.Op) { + if inst, err := x86.VAESIMC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +// Construct and append a VAESIMC instruction to the active function. +// Operates on the global context. +func VAESIMC(mx, x operand.Op) { ctx.VAESIMC(mx, x) } + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +// Construct and append a VAESKEYGENASSIST instruction to the active function. +func (c *Context) VAESKEYGENASSIST(i, mx, x operand.Op) { + if inst, err := x86.VAESKEYGENASSIST(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +// Construct and append a VAESKEYGENASSIST instruction to the active function. +// Operates on the global context. +func VAESKEYGENASSIST(i, mx, x operand.Op) { ctx.VAESKEYGENASSIST(i, mx, x) } + +// 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 +// Construct and append a VANDNPD instruction to the active function. +func (c *Context) VANDNPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDNPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VANDNPD instruction to the active function. +// Operates on the global context. +func VANDNPD(mxy, xy, xy1 operand.Op) { ctx.VANDNPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VANDNPS instruction to the active function. +func (c *Context) VANDNPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDNPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VANDNPS instruction to the active function. +// Operates on the global context. +func VANDNPS(mxy, xy, xy1 operand.Op) { ctx.VANDNPS(mxy, xy, xy1) } + +// 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 +// Construct and append a VANDPD instruction to the active function. +func (c *Context) VANDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VANDPD instruction to the active function. +// Operates on the global context. +func VANDPD(mxy, xy, xy1 operand.Op) { ctx.VANDPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VANDPS instruction to the active function. +func (c *Context) VANDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VANDPS instruction to the active function. +// Operates on the global context. +func VANDPS(mxy, xy, xy1 operand.Op) { ctx.VANDPS(mxy, xy, xy1) } + +// 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 +// Construct and append a VBLENDPD instruction to the active function. +func (c *Context) VBLENDPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VBLENDPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VBLENDPD instruction to the active function. +// Operates on the global context. +func VBLENDPD(i, mxy, xy, xy1 operand.Op) { ctx.VBLENDPD(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VBLENDPS instruction to the active function. +func (c *Context) VBLENDPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VBLENDPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VBLENDPS instruction to the active function. +// Operates on the global context. +func VBLENDPS(i, mxy, xy, xy1 operand.Op) { ctx.VBLENDPS(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VBLENDVPD instruction to the active function. +func (c *Context) VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VBLENDVPD(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VBLENDVPD instruction to the active function. +// Operates on the global context. +func VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) { ctx.VBLENDVPD(xy, mxy, xy1, xy2) } + +// 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 +// Construct and append a VBLENDVPS instruction to the active function. +func (c *Context) VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VBLENDVPS(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VBLENDVPS instruction to the active function. +// Operates on the global context. +func VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) { ctx.VBLENDVPS(xy, mxy, xy1, xy2) } + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +// Construct and append a VBROADCASTF128 instruction to the active function. +func (c *Context) VBROADCASTF128(m, y operand.Op) { + if inst, err := x86.VBROADCASTF128(m, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +// Construct and append a VBROADCASTF128 instruction to the active function. +// Operates on the global context. +func VBROADCASTF128(m, y operand.Op) { ctx.VBROADCASTF128(m, y) } + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +// Construct and append a VBROADCASTI128 instruction to the active function. +func (c *Context) VBROADCASTI128(m, y operand.Op) { + if inst, err := x86.VBROADCASTI128(m, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +// Construct and append a VBROADCASTI128 instruction to the active function. +// Operates on the global context. +func VBROADCASTI128(m, y operand.Op) { ctx.VBROADCASTI128(m, y) } + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +// Construct and append a VBROADCASTSD instruction to the active function. +func (c *Context) VBROADCASTSD(mx, y operand.Op) { + if inst, err := x86.VBROADCASTSD(mx, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +// Construct and append a VBROADCASTSD instruction to the active function. +// Operates on the global context. +func VBROADCASTSD(mx, y operand.Op) { ctx.VBROADCASTSD(mx, y) } + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +// Construct and append a VBROADCASTSS instruction to the active function. +func (c *Context) VBROADCASTSS(mx, xy operand.Op) { + if inst, err := x86.VBROADCASTSS(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +// Construct and append a VBROADCASTSS instruction to the active function. +// Operates on the global context. +func VBROADCASTSS(mx, xy operand.Op) { ctx.VBROADCASTSS(mx, xy) } + +// 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 +// Construct and append a VCMPPD instruction to the active function. +func (c *Context) VCMPPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VCMPPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VCMPPD instruction to the active function. +// Operates on the global context. +func VCMPPD(i, mxy, xy, xy1 operand.Op) { ctx.VCMPPD(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VCMPPS instruction to the active function. +func (c *Context) VCMPPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VCMPPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VCMPPS instruction to the active function. +// Operates on the global context. +func VCMPPS(i, mxy, xy, xy1 operand.Op) { ctx.VCMPPS(i, mxy, xy, xy1) } + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +// Construct and append a VCMPSD instruction to the active function. +func (c *Context) VCMPSD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VCMPSD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +// Construct and append a VCMPSD instruction to the active function. +// Operates on the global context. +func VCMPSD(i, mx, x, x1 operand.Op) { ctx.VCMPSD(i, mx, x, x1) } + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +// Construct and append a VCMPSS instruction to the active function. +func (c *Context) VCMPSS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VCMPSS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +// Construct and append a VCMPSS instruction to the active function. +// Operates on the global context. +func VCMPSS(i, mx, x, x1 operand.Op) { ctx.VCMPSS(i, mx, x, x1) } + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +// Construct and append a VCOMISD instruction to the active function. +func (c *Context) VCOMISD(mx, x operand.Op) { + if inst, err := x86.VCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +// Construct and append a VCOMISD instruction to the active function. +// Operates on the global context. +func VCOMISD(mx, x operand.Op) { ctx.VCOMISD(mx, x) } + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +// Construct and append a VCOMISS instruction to the active function. +func (c *Context) VCOMISS(mx, x operand.Op) { + if inst, err := x86.VCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +// Construct and append a VCOMISS instruction to the active function. +// Operates on the global context. +func VCOMISS(mx, x operand.Op) { ctx.VCOMISS(mx, x) } + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +// Construct and append a VCVTDQ2PD instruction to the active function. +func (c *Context) VCVTDQ2PD(mx, xy operand.Op) { + if inst, err := x86.VCVTDQ2PD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +// Construct and append a VCVTDQ2PD instruction to the active function. +// Operates on the global context. +func VCVTDQ2PD(mx, xy operand.Op) { ctx.VCVTDQ2PD(mx, xy) } + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +// Construct and append a VCVTDQ2PS instruction to the active function. +func (c *Context) VCVTDQ2PS(mxy, xy operand.Op) { + if inst, err := x86.VCVTDQ2PS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +// Construct and append a VCVTDQ2PS instruction to the active function. +// Operates on the global context. +func VCVTDQ2PS(mxy, xy operand.Op) { ctx.VCVTDQ2PS(mxy, xy) } + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +// Construct and append a VCVTPD2DQX instruction to the active function. +func (c *Context) VCVTPD2DQX(mx, x operand.Op) { + if inst, err := x86.VCVTPD2DQX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +// Construct and append a VCVTPD2DQX instruction to the active function. +// Operates on the global context. +func VCVTPD2DQX(mx, x operand.Op) { ctx.VCVTPD2DQX(mx, x) } + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +// Construct and append a VCVTPD2DQY instruction to the active function. +func (c *Context) VCVTPD2DQY(my, x operand.Op) { + if inst, err := x86.VCVTPD2DQY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +// Construct and append a VCVTPD2DQY instruction to the active function. +// Operates on the global context. +func VCVTPD2DQY(my, x operand.Op) { ctx.VCVTPD2DQY(my, x) } + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +// Construct and append a VCVTPD2PSX instruction to the active function. +func (c *Context) VCVTPD2PSX(mx, x operand.Op) { + if inst, err := x86.VCVTPD2PSX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +// Construct and append a VCVTPD2PSX instruction to the active function. +// Operates on the global context. +func VCVTPD2PSX(mx, x operand.Op) { ctx.VCVTPD2PSX(mx, x) } + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +// Construct and append a VCVTPD2PSY instruction to the active function. +func (c *Context) VCVTPD2PSY(my, x operand.Op) { + if inst, err := x86.VCVTPD2PSY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +// Construct and append a VCVTPD2PSY instruction to the active function. +// Operates on the global context. +func VCVTPD2PSY(my, x operand.Op) { ctx.VCVTPD2PSY(my, x) } + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +// Construct and append a VCVTPH2PS instruction to the active function. +func (c *Context) VCVTPH2PS(mx, xy operand.Op) { + if inst, err := x86.VCVTPH2PS(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +// Construct and append a VCVTPH2PS instruction to the active function. +// Operates on the global context. +func VCVTPH2PS(mx, xy operand.Op) { ctx.VCVTPH2PS(mx, xy) } + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +// Construct and append a VCVTPS2DQ instruction to the active function. +func (c *Context) VCVTPS2DQ(mxy, xy operand.Op) { + if inst, err := x86.VCVTPS2DQ(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +// Construct and append a VCVTPS2DQ instruction to the active function. +// Operates on the global context. +func VCVTPS2DQ(mxy, xy operand.Op) { ctx.VCVTPS2DQ(mxy, xy) } + +// 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 +// Construct and append a VCVTPS2PD instruction to the active function. +func (c *Context) VCVTPS2PD(mx, xy operand.Op) { + if inst, err := x86.VCVTPS2PD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VCVTPS2PD instruction to the active function. +// Operates on the global context. +func VCVTPS2PD(mx, xy operand.Op) { ctx.VCVTPS2PD(mx, xy) } + +// 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 +// Construct and append a VCVTPS2PH instruction to the active function. +func (c *Context) VCVTPS2PH(i, xy, mx operand.Op) { + if inst, err := x86.VCVTPS2PH(i, xy, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VCVTPS2PH instruction to the active function. +// Operates on the global context. +func VCVTPS2PH(i, xy, mx operand.Op) { ctx.VCVTPS2PH(i, xy, mx) } + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +// Construct and append a VCVTSD2SI instruction to the active function. +func (c *Context) VCVTSD2SI(mx, r operand.Op) { + if inst, err := x86.VCVTSD2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +// Construct and append a VCVTSD2SI instruction to the active function. +// Operates on the global context. +func VCVTSD2SI(mx, r operand.Op) { ctx.VCVTSD2SI(mx, r) } + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +// Construct and append a VCVTSD2SIQ instruction to the active function. +func (c *Context) VCVTSD2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTSD2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +// Construct and append a VCVTSD2SIQ instruction to the active function. +// Operates on the global context. +func VCVTSD2SIQ(mx, r operand.Op) { ctx.VCVTSD2SIQ(mx, r) } + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +// Construct and append a VCVTSD2SS instruction to the active function. +func (c *Context) VCVTSD2SS(mx, x, x1 operand.Op) { + if inst, err := x86.VCVTSD2SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +// Construct and append a VCVTSD2SS instruction to the active function. +// Operates on the global context. +func VCVTSD2SS(mx, x, x1 operand.Op) { ctx.VCVTSD2SS(mx, x, x1) } + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +// Construct and append a VCVTSI2SDL instruction to the active function. +func (c *Context) VCVTSI2SDL(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SDL(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +// Construct and append a VCVTSI2SDL instruction to the active function. +// Operates on the global context. +func VCVTSI2SDL(mr, x, x1 operand.Op) { ctx.VCVTSI2SDL(mr, x, x1) } + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +// Construct and append a VCVTSI2SDQ instruction to the active function. +func (c *Context) VCVTSI2SDQ(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SDQ(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +// Construct and append a VCVTSI2SDQ instruction to the active function. +// Operates on the global context. +func VCVTSI2SDQ(mr, x, x1 operand.Op) { ctx.VCVTSI2SDQ(mr, x, x1) } + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +// Construct and append a VCVTSI2SSL instruction to the active function. +func (c *Context) VCVTSI2SSL(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SSL(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +// Construct and append a VCVTSI2SSL instruction to the active function. +// Operates on the global context. +func VCVTSI2SSL(mr, x, x1 operand.Op) { ctx.VCVTSI2SSL(mr, x, x1) } + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +// Construct and append a VCVTSI2SSQ instruction to the active function. +func (c *Context) VCVTSI2SSQ(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SSQ(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +// Construct and append a VCVTSI2SSQ instruction to the active function. +// Operates on the global context. +func VCVTSI2SSQ(mr, x, x1 operand.Op) { ctx.VCVTSI2SSQ(mr, x, x1) } + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +// Construct and append a VCVTSS2SD instruction to the active function. +func (c *Context) VCVTSS2SD(mx, x, x1 operand.Op) { + if inst, err := x86.VCVTSS2SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +// Construct and append a VCVTSS2SD instruction to the active function. +// Operates on the global context. +func VCVTSS2SD(mx, x, x1 operand.Op) { ctx.VCVTSS2SD(mx, x, x1) } + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +// Construct and append a VCVTSS2SI instruction to the active function. +func (c *Context) VCVTSS2SI(mx, r operand.Op) { + if inst, err := x86.VCVTSS2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +// Construct and append a VCVTSS2SI instruction to the active function. +// Operates on the global context. +func VCVTSS2SI(mx, r operand.Op) { ctx.VCVTSS2SI(mx, r) } + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +// Construct and append a VCVTSS2SIQ instruction to the active function. +func (c *Context) VCVTSS2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTSS2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +// Construct and append a VCVTSS2SIQ instruction to the active function. +// Operates on the global context. +func VCVTSS2SIQ(mx, r operand.Op) { ctx.VCVTSS2SIQ(mx, r) } + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +// Construct and append a VCVTTPD2DQX instruction to the active function. +func (c *Context) VCVTTPD2DQX(mx, x operand.Op) { + if inst, err := x86.VCVTTPD2DQX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +// Construct and append a VCVTTPD2DQX instruction to the active function. +// Operates on the global context. +func VCVTTPD2DQX(mx, x operand.Op) { ctx.VCVTTPD2DQX(mx, x) } + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +// Construct and append a VCVTTPD2DQY instruction to the active function. +func (c *Context) VCVTTPD2DQY(my, x operand.Op) { + if inst, err := x86.VCVTTPD2DQY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +// Construct and append a VCVTTPD2DQY instruction to the active function. +// Operates on the global context. +func VCVTTPD2DQY(my, x operand.Op) { ctx.VCVTTPD2DQY(my, x) } + +// 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 +// Construct and append a VCVTTPS2DQ instruction to the active function. +func (c *Context) VCVTTPS2DQ(mxy, xy operand.Op) { + if inst, err := x86.VCVTTPS2DQ(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VCVTTPS2DQ instruction to the active function. +// Operates on the global context. +func VCVTTPS2DQ(mxy, xy operand.Op) { ctx.VCVTTPS2DQ(mxy, xy) } + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +// Construct and append a VCVTTSD2SI instruction to the active function. +func (c *Context) VCVTTSD2SI(mx, r operand.Op) { + if inst, err := x86.VCVTTSD2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +// Construct and append a VCVTTSD2SI instruction to the active function. +// Operates on the global context. +func VCVTTSD2SI(mx, r operand.Op) { ctx.VCVTTSD2SI(mx, r) } + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +// Construct and append a VCVTTSD2SIQ instruction to the active function. +func (c *Context) VCVTTSD2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTTSD2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +// Construct and append a VCVTTSD2SIQ instruction to the active function. +// Operates on the global context. +func VCVTTSD2SIQ(mx, r operand.Op) { ctx.VCVTTSD2SIQ(mx, r) } + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +// Construct and append a VCVTTSS2SI instruction to the active function. +func (c *Context) VCVTTSS2SI(mx, r operand.Op) { + if inst, err := x86.VCVTTSS2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +// Construct and append a VCVTTSS2SI instruction to the active function. +// Operates on the global context. +func VCVTTSS2SI(mx, r operand.Op) { ctx.VCVTTSS2SI(mx, r) } + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +// Construct and append a VCVTTSS2SIQ instruction to the active function. +func (c *Context) VCVTTSS2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTTSS2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +// Construct and append a VCVTTSS2SIQ instruction to the active function. +// Operates on the global context. +func VCVTTSS2SIQ(mx, r operand.Op) { ctx.VCVTTSS2SIQ(mx, r) } + +// 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 +// Construct and append a VDIVPD instruction to the active function. +func (c *Context) VDIVPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDIVPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VDIVPD instruction to the active function. +// Operates on the global context. +func VDIVPD(mxy, xy, xy1 operand.Op) { ctx.VDIVPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VDIVPS instruction to the active function. +func (c *Context) VDIVPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDIVPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VDIVPS instruction to the active function. +// Operates on the global context. +func VDIVPS(mxy, xy, xy1 operand.Op) { ctx.VDIVPS(mxy, xy, xy1) } + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +// Construct and append a VDIVSD instruction to the active function. +func (c *Context) VDIVSD(mx, x, x1 operand.Op) { + if inst, err := x86.VDIVSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +// Construct and append a VDIVSD instruction to the active function. +// Operates on the global context. +func VDIVSD(mx, x, x1 operand.Op) { ctx.VDIVSD(mx, x, x1) } + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +// Construct and append a VDIVSS instruction to the active function. +func (c *Context) VDIVSS(mx, x, x1 operand.Op) { + if inst, err := x86.VDIVSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +// Construct and append a VDIVSS instruction to the active function. +// Operates on the global context. +func VDIVSS(mx, x, x1 operand.Op) { ctx.VDIVSS(mx, x, x1) } + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +// Construct and append a VDPPD instruction to the active function. +func (c *Context) VDPPD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VDPPD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +// Construct and append a VDPPD instruction to the active function. +// Operates on the global context. +func VDPPD(i, mx, x, x1 operand.Op) { ctx.VDPPD(i, mx, x, x1) } + +// 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 +// Construct and append a VDPPS instruction to the active function. +func (c *Context) VDPPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDPPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VDPPS instruction to the active function. +// Operates on the global context. +func VDPPS(i, mxy, xy, xy1 operand.Op) { ctx.VDPPS(i, mxy, xy, xy1) } + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +// Construct and append a VEXTRACTF128 instruction to the active function. +func (c *Context) VEXTRACTF128(i, y, mx operand.Op) { + if inst, err := x86.VEXTRACTF128(i, y, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +// Construct and append a VEXTRACTF128 instruction to the active function. +// Operates on the global context. +func VEXTRACTF128(i, y, mx operand.Op) { ctx.VEXTRACTF128(i, y, mx) } + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +// Construct and append a VEXTRACTI128 instruction to the active function. +func (c *Context) VEXTRACTI128(i, y, mx operand.Op) { + if inst, err := x86.VEXTRACTI128(i, y, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +// Construct and append a VEXTRACTI128 instruction to the active function. +// Operates on the global context. +func VEXTRACTI128(i, y, mx operand.Op) { ctx.VEXTRACTI128(i, y, mx) } + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +// Construct and append a VEXTRACTPS instruction to the active function. +func (c *Context) VEXTRACTPS(i, x, mr operand.Op) { + if inst, err := x86.VEXTRACTPS(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +// Construct and append a VEXTRACTPS instruction to the active function. +// Operates on the global context. +func VEXTRACTPS(i, x, mr operand.Op) { ctx.VEXTRACTPS(i, x, mr) } + +// 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 +// Construct and append a VFMADD132PD instruction to the active function. +func (c *Context) VFMADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD132PD instruction to the active function. +// Operates on the global context. +func VFMADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADD132PS instruction to the active function. +func (c *Context) VFMADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD132PS instruction to the active function. +// Operates on the global context. +func VFMADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD132PS(mxy, xy, xy1) } + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +// Construct and append a VFMADD132SD instruction to the active function. +func (c *Context) VFMADD132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +// Construct and append a VFMADD132SD instruction to the active function. +// Operates on the global context. +func VFMADD132SD(mx, x, x1 operand.Op) { ctx.VFMADD132SD(mx, x, x1) } + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +// Construct and append a VFMADD132SS instruction to the active function. +func (c *Context) VFMADD132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +// Construct and append a VFMADD132SS instruction to the active function. +// Operates on the global context. +func VFMADD132SS(mx, x, x1 operand.Op) { ctx.VFMADD132SS(mx, x, x1) } + +// 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 +// Construct and append a VFMADD213PD instruction to the active function. +func (c *Context) VFMADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD213PD instruction to the active function. +// Operates on the global context. +func VFMADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADD213PS instruction to the active function. +func (c *Context) VFMADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD213PS instruction to the active function. +// Operates on the global context. +func VFMADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD213PS(mxy, xy, xy1) } + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +// Construct and append a VFMADD213SD instruction to the active function. +func (c *Context) VFMADD213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +// Construct and append a VFMADD213SD instruction to the active function. +// Operates on the global context. +func VFMADD213SD(mx, x, x1 operand.Op) { ctx.VFMADD213SD(mx, x, x1) } + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +// Construct and append a VFMADD213SS instruction to the active function. +func (c *Context) VFMADD213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +// Construct and append a VFMADD213SS instruction to the active function. +// Operates on the global context. +func VFMADD213SS(mx, x, x1 operand.Op) { ctx.VFMADD213SS(mx, x, x1) } + +// 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 +// Construct and append a VFMADD231PD instruction to the active function. +func (c *Context) VFMADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD231PD instruction to the active function. +// Operates on the global context. +func VFMADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADD231PS instruction to the active function. +func (c *Context) VFMADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADD231PS instruction to the active function. +// Operates on the global context. +func VFMADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD231PS(mxy, xy, xy1) } + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +// Construct and append a VFMADD231SD instruction to the active function. +func (c *Context) VFMADD231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +// Construct and append a VFMADD231SD instruction to the active function. +// Operates on the global context. +func VFMADD231SD(mx, x, x1 operand.Op) { ctx.VFMADD231SD(mx, x, x1) } + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +// Construct and append a VFMADD231SS instruction to the active function. +func (c *Context) VFMADD231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +// Construct and append a VFMADD231SS instruction to the active function. +// Operates on the global context. +func VFMADD231SS(mx, x, x1 operand.Op) { ctx.VFMADD231SS(mx, x, x1) } + +// 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 +// Construct and append a VFMADDSUB132PD instruction to the active function. +func (c *Context) VFMADDSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB132PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADDSUB132PS instruction to the active function. +func (c *Context) VFMADDSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB132PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB132PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADDSUB213PD instruction to the active function. +func (c *Context) VFMADDSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB213PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADDSUB213PS instruction to the active function. +func (c *Context) VFMADDSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB213PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB213PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADDSUB231PD instruction to the active function. +func (c *Context) VFMADDSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB231PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMADDSUB231PS instruction to the active function. +func (c *Context) VFMADDSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMADDSUB231PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB231PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUB132PD instruction to the active function. +func (c *Context) VFMSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB132PD instruction to the active function. +// Operates on the global context. +func VFMSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUB132PS instruction to the active function. +func (c *Context) VFMSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB132PS instruction to the active function. +// Operates on the global context. +func VFMSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB132PS(mxy, xy, xy1) } + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +// Construct and append a VFMSUB132SD instruction to the active function. +func (c *Context) VFMSUB132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +// Construct and append a VFMSUB132SD instruction to the active function. +// Operates on the global context. +func VFMSUB132SD(mx, x, x1 operand.Op) { ctx.VFMSUB132SD(mx, x, x1) } + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +// Construct and append a VFMSUB132SS instruction to the active function. +func (c *Context) VFMSUB132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +// Construct and append a VFMSUB132SS instruction to the active function. +// Operates on the global context. +func VFMSUB132SS(mx, x, x1 operand.Op) { ctx.VFMSUB132SS(mx, x, x1) } + +// 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 +// Construct and append a VFMSUB213PD instruction to the active function. +func (c *Context) VFMSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB213PD instruction to the active function. +// Operates on the global context. +func VFMSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUB213PS instruction to the active function. +func (c *Context) VFMSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB213PS instruction to the active function. +// Operates on the global context. +func VFMSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB213PS(mxy, xy, xy1) } + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +// Construct and append a VFMSUB213SD instruction to the active function. +func (c *Context) VFMSUB213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +// Construct and append a VFMSUB213SD instruction to the active function. +// Operates on the global context. +func VFMSUB213SD(mx, x, x1 operand.Op) { ctx.VFMSUB213SD(mx, x, x1) } + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +// Construct and append a VFMSUB213SS instruction to the active function. +func (c *Context) VFMSUB213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +// Construct and append a VFMSUB213SS instruction to the active function. +// Operates on the global context. +func VFMSUB213SS(mx, x, x1 operand.Op) { ctx.VFMSUB213SS(mx, x, x1) } + +// 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 +// Construct and append a VFMSUB231PD instruction to the active function. +func (c *Context) VFMSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB231PD instruction to the active function. +// Operates on the global context. +func VFMSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUB231PS instruction to the active function. +func (c *Context) VFMSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUB231PS instruction to the active function. +// Operates on the global context. +func VFMSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB231PS(mxy, xy, xy1) } + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +// Construct and append a VFMSUB231SD instruction to the active function. +func (c *Context) VFMSUB231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +// Construct and append a VFMSUB231SD instruction to the active function. +// Operates on the global context. +func VFMSUB231SD(mx, x, x1 operand.Op) { ctx.VFMSUB231SD(mx, x, x1) } + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +// Construct and append a VFMSUB231SS instruction to the active function. +func (c *Context) VFMSUB231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +// Construct and append a VFMSUB231SS instruction to the active function. +// Operates on the global context. +func VFMSUB231SS(mx, x, x1 operand.Op) { ctx.VFMSUB231SS(mx, x, x1) } + +// 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 +// Construct and append a VFMSUBADD132PD instruction to the active function. +func (c *Context) VFMSUBADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD132PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUBADD132PS instruction to the active function. +func (c *Context) VFMSUBADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD132PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD132PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUBADD213PD instruction to the active function. +func (c *Context) VFMSUBADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD213PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUBADD213PS instruction to the active function. +func (c *Context) VFMSUBADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD213PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD213PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUBADD231PD instruction to the active function. +func (c *Context) VFMSUBADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD231PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFMSUBADD231PS instruction to the active function. +func (c *Context) VFMSUBADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFMSUBADD231PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD231PS(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMADD132PD instruction to the active function. +func (c *Context) VFNMADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD132PD instruction to the active function. +// Operates on the global context. +func VFNMADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMADD132PS instruction to the active function. +func (c *Context) VFNMADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD132PS instruction to the active function. +// Operates on the global context. +func VFNMADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD132PS(mxy, xy, xy1) } + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +// Construct and append a VFNMADD132SD instruction to the active function. +func (c *Context) VFNMADD132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +// Construct and append a VFNMADD132SD instruction to the active function. +// Operates on the global context. +func VFNMADD132SD(mx, x, x1 operand.Op) { ctx.VFNMADD132SD(mx, x, x1) } + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +// Construct and append a VFNMADD132SS instruction to the active function. +func (c *Context) VFNMADD132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +// Construct and append a VFNMADD132SS instruction to the active function. +// Operates on the global context. +func VFNMADD132SS(mx, x, x1 operand.Op) { ctx.VFNMADD132SS(mx, x, x1) } + +// 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 +// Construct and append a VFNMADD213PD instruction to the active function. +func (c *Context) VFNMADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD213PD instruction to the active function. +// Operates on the global context. +func VFNMADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMADD213PS instruction to the active function. +func (c *Context) VFNMADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD213PS instruction to the active function. +// Operates on the global context. +func VFNMADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD213PS(mxy, xy, xy1) } + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +// Construct and append a VFNMADD213SD instruction to the active function. +func (c *Context) VFNMADD213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +// Construct and append a VFNMADD213SD instruction to the active function. +// Operates on the global context. +func VFNMADD213SD(mx, x, x1 operand.Op) { ctx.VFNMADD213SD(mx, x, x1) } + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +// Construct and append a VFNMADD213SS instruction to the active function. +func (c *Context) VFNMADD213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +// Construct and append a VFNMADD213SS instruction to the active function. +// Operates on the global context. +func VFNMADD213SS(mx, x, x1 operand.Op) { ctx.VFNMADD213SS(mx, x, x1) } + +// 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 +// Construct and append a VFNMADD231PD instruction to the active function. +func (c *Context) VFNMADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD231PD instruction to the active function. +// Operates on the global context. +func VFNMADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMADD231PS instruction to the active function. +func (c *Context) VFNMADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMADD231PS instruction to the active function. +// Operates on the global context. +func VFNMADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD231PS(mxy, xy, xy1) } + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +// Construct and append a VFNMADD231SD instruction to the active function. +func (c *Context) VFNMADD231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +// Construct and append a VFNMADD231SD instruction to the active function. +// Operates on the global context. +func VFNMADD231SD(mx, x, x1 operand.Op) { ctx.VFNMADD231SD(mx, x, x1) } + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +// Construct and append a VFNMADD231SS instruction to the active function. +func (c *Context) VFNMADD231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +// Construct and append a VFNMADD231SS instruction to the active function. +// Operates on the global context. +func VFNMADD231SS(mx, x, x1 operand.Op) { ctx.VFNMADD231SS(mx, x, x1) } + +// 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 +// Construct and append a VFNMSUB132PD instruction to the active function. +func (c *Context) VFNMSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB132PD instruction to the active function. +// Operates on the global context. +func VFNMSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB132PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMSUB132PS instruction to the active function. +func (c *Context) VFNMSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB132PS instruction to the active function. +// Operates on the global context. +func VFNMSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB132PS(mxy, xy, xy1) } + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +// Construct and append a VFNMSUB132SD instruction to the active function. +func (c *Context) VFNMSUB132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +// Construct and append a VFNMSUB132SD instruction to the active function. +// Operates on the global context. +func VFNMSUB132SD(mx, x, x1 operand.Op) { ctx.VFNMSUB132SD(mx, x, x1) } + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +// Construct and append a VFNMSUB132SS instruction to the active function. +func (c *Context) VFNMSUB132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +// Construct and append a VFNMSUB132SS instruction to the active function. +// Operates on the global context. +func VFNMSUB132SS(mx, x, x1 operand.Op) { ctx.VFNMSUB132SS(mx, x, x1) } + +// 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 +// Construct and append a VFNMSUB213PD instruction to the active function. +func (c *Context) VFNMSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB213PD instruction to the active function. +// Operates on the global context. +func VFNMSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB213PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMSUB213PS instruction to the active function. +func (c *Context) VFNMSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB213PS instruction to the active function. +// Operates on the global context. +func VFNMSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB213PS(mxy, xy, xy1) } + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +// Construct and append a VFNMSUB213SD instruction to the active function. +func (c *Context) VFNMSUB213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +// Construct and append a VFNMSUB213SD instruction to the active function. +// Operates on the global context. +func VFNMSUB213SD(mx, x, x1 operand.Op) { ctx.VFNMSUB213SD(mx, x, x1) } + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +// Construct and append a VFNMSUB213SS instruction to the active function. +func (c *Context) VFNMSUB213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +// Construct and append a VFNMSUB213SS instruction to the active function. +// Operates on the global context. +func VFNMSUB213SS(mx, x, x1 operand.Op) { ctx.VFNMSUB213SS(mx, x, x1) } + +// 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 +// Construct and append a VFNMSUB231PD instruction to the active function. +func (c *Context) VFNMSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB231PD instruction to the active function. +// Operates on the global context. +func VFNMSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB231PD(mxy, xy, xy1) } + +// 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 +// Construct and append a VFNMSUB231PS instruction to the active function. +func (c *Context) VFNMSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VFNMSUB231PS instruction to the active function. +// Operates on the global context. +func VFNMSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB231PS(mxy, xy, xy1) } + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +// Construct and append a VFNMSUB231SD instruction to the active function. +func (c *Context) VFNMSUB231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +// Construct and append a VFNMSUB231SD instruction to the active function. +// Operates on the global context. +func VFNMSUB231SD(mx, x, x1 operand.Op) { ctx.VFNMSUB231SD(mx, x, x1) } + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +// Construct and append a VFNMSUB231SS instruction to the active function. +func (c *Context) VFNMSUB231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +// Construct and append a VFNMSUB231SS instruction to the active function. +// Operates on the global context. +func VFNMSUB231SS(mx, x, x1 operand.Op) { ctx.VFNMSUB231SS(mx, x, x1) } + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +// Construct and append a VGATHERDPD instruction to the active function. +func (c *Context) VGATHERDPD(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERDPD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +// Construct and append a VGATHERDPD instruction to the active function. +// Operates on the global context. +func VGATHERDPD(xy, v, xy1 operand.Op) { ctx.VGATHERDPD(xy, v, xy1) } + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +// Construct and append a VGATHERDPS instruction to the active function. +func (c *Context) VGATHERDPS(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERDPS(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +// Construct and append a VGATHERDPS instruction to the active function. +// Operates on the global context. +func VGATHERDPS(xy, v, xy1 operand.Op) { ctx.VGATHERDPS(xy, v, xy1) } + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +// Construct and append a VGATHERQPD instruction to the active function. +func (c *Context) VGATHERQPD(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERQPD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +// Construct and append a VGATHERQPD instruction to the active function. +// Operates on the global context. +func VGATHERQPD(xy, v, xy1 operand.Op) { ctx.VGATHERQPD(xy, v, xy1) } + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +// Construct and append a VGATHERQPS instruction to the active function. +func (c *Context) VGATHERQPS(x, v, x1 operand.Op) { + if inst, err := x86.VGATHERQPS(x, v, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +// Construct and append a VGATHERQPS instruction to the active function. +// Operates on the global context. +func VGATHERQPS(x, v, x1 operand.Op) { ctx.VGATHERQPS(x, v, x1) } + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +// Construct and append a VHADDPD instruction to the active function. +func (c *Context) VHADDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHADDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +// Construct and append a VHADDPD instruction to the active function. +// Operates on the global context. +func VHADDPD(mxy, xy, xy1 operand.Op) { ctx.VHADDPD(mxy, xy, xy1) } + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +// Construct and append a VHADDPS instruction to the active function. +func (c *Context) VHADDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHADDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +// Construct and append a VHADDPS instruction to the active function. +// Operates on the global context. +func VHADDPS(mxy, xy, xy1 operand.Op) { ctx.VHADDPS(mxy, xy, xy1) } + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +// Construct and append a VHSUBPD instruction to the active function. +func (c *Context) VHSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +// Construct and append a VHSUBPD instruction to the active function. +// Operates on the global context. +func VHSUBPD(mxy, xy, xy1 operand.Op) { ctx.VHSUBPD(mxy, xy, xy1) } + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +// Construct and append a VHSUBPS instruction to the active function. +func (c *Context) VHSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +// Construct and append a VHSUBPS instruction to the active function. +// Operates on the global context. +func VHSUBPS(mxy, xy, xy1 operand.Op) { ctx.VHSUBPS(mxy, xy, xy1) } + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +// Construct and append a VINSERTF128 instruction to the active function. +func (c *Context) VINSERTF128(i, mx, y, y1 operand.Op) { + if inst, err := x86.VINSERTF128(i, mx, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +// Construct and append a VINSERTF128 instruction to the active function. +// Operates on the global context. +func VINSERTF128(i, mx, y, y1 operand.Op) { ctx.VINSERTF128(i, mx, y, y1) } + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +// Construct and append a VINSERTI128 instruction to the active function. +func (c *Context) VINSERTI128(i, mx, y, y1 operand.Op) { + if inst, err := x86.VINSERTI128(i, mx, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +// Construct and append a VINSERTI128 instruction to the active function. +// Operates on the global context. +func VINSERTI128(i, mx, y, y1 operand.Op) { ctx.VINSERTI128(i, mx, y, y1) } + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +// Construct and append a VINSERTPS instruction to the active function. +func (c *Context) VINSERTPS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VINSERTPS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +// Construct and append a VINSERTPS instruction to the active function. +// Operates on the global context. +func VINSERTPS(i, mx, x, x1 operand.Op) { ctx.VINSERTPS(i, mx, x, x1) } + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +// Construct and append a VLDDQU instruction to the active function. +func (c *Context) VLDDQU(m, xy operand.Op) { + if inst, err := x86.VLDDQU(m, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +// Construct and append a VLDDQU instruction to the active function. +// Operates on the global context. +func VLDDQU(m, xy operand.Op) { ctx.VLDDQU(m, xy) } + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +// Construct and append a VLDMXCSR instruction to the active function. +func (c *Context) VLDMXCSR(m operand.Op) { + if inst, err := x86.VLDMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +// Construct and append a VLDMXCSR instruction to the active function. +// Operates on the global context. +func VLDMXCSR(m operand.Op) { ctx.VLDMXCSR(m) } + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +// Construct and append a VMASKMOVDQU instruction to the active function. +func (c *Context) VMASKMOVDQU(x, x1 operand.Op) { + if inst, err := x86.VMASKMOVDQU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +// Construct and append a VMASKMOVDQU instruction to the active function. +// Operates on the global context. +func VMASKMOVDQU(x, x1 operand.Op) { ctx.VMASKMOVDQU(x, x1) } + +// 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 +// Construct and append a VMASKMOVPD instruction to the active function. +func (c *Context) VMASKMOVPD(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VMASKMOVPD(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMASKMOVPD instruction to the active function. +// Operates on the global context. +func VMASKMOVPD(mxy, xy, mxy1 operand.Op) { ctx.VMASKMOVPD(mxy, xy, mxy1) } + +// 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 +// Construct and append a VMASKMOVPS instruction to the active function. +func (c *Context) VMASKMOVPS(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VMASKMOVPS(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMASKMOVPS instruction to the active function. +// Operates on the global context. +func VMASKMOVPS(mxy, xy, mxy1 operand.Op) { ctx.VMASKMOVPS(mxy, xy, mxy1) } + +// 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 +// Construct and append a VMAXPD instruction to the active function. +func (c *Context) VMAXPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMAXPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMAXPD instruction to the active function. +// Operates on the global context. +func VMAXPD(mxy, xy, xy1 operand.Op) { ctx.VMAXPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VMAXPS instruction to the active function. +func (c *Context) VMAXPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMAXPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMAXPS instruction to the active function. +// Operates on the global context. +func VMAXPS(mxy, xy, xy1 operand.Op) { ctx.VMAXPS(mxy, xy, xy1) } + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +// Construct and append a VMAXSD instruction to the active function. +func (c *Context) VMAXSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMAXSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +// Construct and append a VMAXSD instruction to the active function. +// Operates on the global context. +func VMAXSD(mx, x, x1 operand.Op) { ctx.VMAXSD(mx, x, x1) } + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +// Construct and append a VMAXSS instruction to the active function. +func (c *Context) VMAXSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMAXSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +// Construct and append a VMAXSS instruction to the active function. +// Operates on the global context. +func VMAXSS(mx, x, x1 operand.Op) { ctx.VMAXSS(mx, x, x1) } + +// 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 +// Construct and append a VMINPD instruction to the active function. +func (c *Context) VMINPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMINPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMINPD instruction to the active function. +// Operates on the global context. +func VMINPD(mxy, xy, xy1 operand.Op) { ctx.VMINPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VMINPS instruction to the active function. +func (c *Context) VMINPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMINPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMINPS instruction to the active function. +// Operates on the global context. +func VMINPS(mxy, xy, xy1 operand.Op) { ctx.VMINPS(mxy, xy, xy1) } + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +// Construct and append a VMINSD instruction to the active function. +func (c *Context) VMINSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMINSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +// Construct and append a VMINSD instruction to the active function. +// Operates on the global context. +func VMINSD(mx, x, x1 operand.Op) { ctx.VMINSD(mx, x, x1) } + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +// Construct and append a VMINSS instruction to the active function. +func (c *Context) VMINSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMINSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +// Construct and append a VMINSS instruction to the active function. +// Operates on the global context. +func VMINSS(mx, x, x1 operand.Op) { ctx.VMINSS(mx, x, x1) } + +// 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 +// Construct and append a VMOVAPD instruction to the active function. +func (c *Context) VMOVAPD(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVAPD(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMOVAPD instruction to the active function. +// Operates on the global context. +func VMOVAPD(mxy, mxy1 operand.Op) { ctx.VMOVAPD(mxy, mxy1) } + +// 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 +// Construct and append a VMOVAPS instruction to the active function. +func (c *Context) VMOVAPS(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVAPS(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMOVAPS instruction to the active function. +// Operates on the global context. +func VMOVAPS(mxy, mxy1 operand.Op) { ctx.VMOVAPS(mxy, mxy1) } + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +// Construct and append a VMOVD instruction to the active function. +func (c *Context) VMOVD(mrx, mrx1 operand.Op) { + if inst, err := x86.VMOVD(mrx, mrx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +// Construct and append a VMOVD instruction to the active function. +// Operates on the global context. +func VMOVD(mrx, mrx1 operand.Op) { ctx.VMOVD(mrx, mrx1) } + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +// Construct and append a VMOVDDUP instruction to the active function. +func (c *Context) VMOVDDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVDDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +// Construct and append a VMOVDDUP instruction to the active function. +// Operates on the global context. +func VMOVDDUP(mxy, xy operand.Op) { ctx.VMOVDDUP(mxy, xy) } + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +// Construct and append a VMOVDQA instruction to the active function. +func (c *Context) VMOVDQA(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVDQA(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +// Construct and append a VMOVDQA instruction to the active function. +// Operates on the global context. +func VMOVDQA(mxy, mxy1 operand.Op) { ctx.VMOVDQA(mxy, mxy1) } + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +// Construct and append a VMOVDQU instruction to the active function. +func (c *Context) VMOVDQU(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVDQU(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +// Construct and append a VMOVDQU instruction to the active function. +// Operates on the global context. +func VMOVDQU(mxy, mxy1 operand.Op) { ctx.VMOVDQU(mxy, mxy1) } + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +// Construct and append a VMOVHLPS instruction to the active function. +func (c *Context) VMOVHLPS(x, x1, x2 operand.Op) { + if inst, err := x86.VMOVHLPS(x, x1, x2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +// Construct and append a VMOVHLPS instruction to the active function. +// Operates on the global context. +func VMOVHLPS(x, x1, x2 operand.Op) { ctx.VMOVHLPS(x, x1, x2) } + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +// Construct and append a VMOVHPD instruction to the active function. +func (c *Context) VMOVHPD(ops ...operand.Op) { + if inst, err := x86.VMOVHPD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +// Construct and append a VMOVHPD instruction to the active function. +// Operates on the global context. +func VMOVHPD(ops ...operand.Op) { ctx.VMOVHPD(ops...) } + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +// Construct and append a VMOVHPS instruction to the active function. +func (c *Context) VMOVHPS(ops ...operand.Op) { + if inst, err := x86.VMOVHPS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +// Construct and append a VMOVHPS instruction to the active function. +// Operates on the global context. +func VMOVHPS(ops ...operand.Op) { ctx.VMOVHPS(ops...) } + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +// Construct and append a VMOVLHPS instruction to the active function. +func (c *Context) VMOVLHPS(x, x1, x2 operand.Op) { + if inst, err := x86.VMOVLHPS(x, x1, x2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +// Construct and append a VMOVLHPS instruction to the active function. +// Operates on the global context. +func VMOVLHPS(x, x1, x2 operand.Op) { ctx.VMOVLHPS(x, x1, x2) } + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +// Construct and append a VMOVLPD instruction to the active function. +func (c *Context) VMOVLPD(ops ...operand.Op) { + if inst, err := x86.VMOVLPD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +// Construct and append a VMOVLPD instruction to the active function. +// Operates on the global context. +func VMOVLPD(ops ...operand.Op) { ctx.VMOVLPD(ops...) } + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +// Construct and append a VMOVLPS instruction to the active function. +func (c *Context) VMOVLPS(ops ...operand.Op) { + if inst, err := x86.VMOVLPS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +// Construct and append a VMOVLPS instruction to the active function. +// Operates on the global context. +func VMOVLPS(ops ...operand.Op) { ctx.VMOVLPS(ops...) } + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +// Construct and append a VMOVMSKPD instruction to the active function. +func (c *Context) VMOVMSKPD(xy, r operand.Op) { + if inst, err := x86.VMOVMSKPD(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +// Construct and append a VMOVMSKPD instruction to the active function. +// Operates on the global context. +func VMOVMSKPD(xy, r operand.Op) { ctx.VMOVMSKPD(xy, r) } + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +// Construct and append a VMOVMSKPS instruction to the active function. +func (c *Context) VMOVMSKPS(xy, r operand.Op) { + if inst, err := x86.VMOVMSKPS(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +// Construct and append a VMOVMSKPS instruction to the active function. +// Operates on the global context. +func VMOVMSKPS(xy, r operand.Op) { ctx.VMOVMSKPS(xy, r) } + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +// Construct and append a VMOVNTDQ instruction to the active function. +func (c *Context) VMOVNTDQ(xy, m operand.Op) { + if inst, err := x86.VMOVNTDQ(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +// Construct and append a VMOVNTDQ instruction to the active function. +// Operates on the global context. +func VMOVNTDQ(xy, m operand.Op) { ctx.VMOVNTDQ(xy, m) } + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +// Construct and append a VMOVNTDQA instruction to the active function. +func (c *Context) VMOVNTDQA(m, xy operand.Op) { + if inst, err := x86.VMOVNTDQA(m, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +// Construct and append a VMOVNTDQA instruction to the active function. +// Operates on the global context. +func VMOVNTDQA(m, xy operand.Op) { ctx.VMOVNTDQA(m, xy) } + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +// Construct and append a VMOVNTPD instruction to the active function. +func (c *Context) VMOVNTPD(xy, m operand.Op) { + if inst, err := x86.VMOVNTPD(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +// Construct and append a VMOVNTPD instruction to the active function. +// Operates on the global context. +func VMOVNTPD(xy, m operand.Op) { ctx.VMOVNTPD(xy, m) } + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +// Construct and append a VMOVNTPS instruction to the active function. +func (c *Context) VMOVNTPS(xy, m operand.Op) { + if inst, err := x86.VMOVNTPS(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +// Construct and append a VMOVNTPS instruction to the active function. +// Operates on the global context. +func VMOVNTPS(xy, m operand.Op) { ctx.VMOVNTPS(xy, m) } + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +// Construct and append a VMOVQ instruction to the active function. +func (c *Context) VMOVQ(mrx, mrx1 operand.Op) { + if inst, err := x86.VMOVQ(mrx, mrx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +// Construct and append a VMOVQ instruction to the active function. +// Operates on the global context. +func VMOVQ(mrx, mrx1 operand.Op) { ctx.VMOVQ(mrx, mrx1) } + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +// Construct and append a VMOVSD instruction to the active function. +func (c *Context) VMOVSD(ops ...operand.Op) { + if inst, err := x86.VMOVSD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +// Construct and append a VMOVSD instruction to the active function. +// Operates on the global context. +func VMOVSD(ops ...operand.Op) { ctx.VMOVSD(ops...) } + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +// Construct and append a VMOVSHDUP instruction to the active function. +func (c *Context) VMOVSHDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVSHDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +// Construct and append a VMOVSHDUP instruction to the active function. +// Operates on the global context. +func VMOVSHDUP(mxy, xy operand.Op) { ctx.VMOVSHDUP(mxy, xy) } + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +// Construct and append a VMOVSLDUP instruction to the active function. +func (c *Context) VMOVSLDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVSLDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +// Construct and append a VMOVSLDUP instruction to the active function. +// Operates on the global context. +func VMOVSLDUP(mxy, xy operand.Op) { ctx.VMOVSLDUP(mxy, xy) } + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +// Construct and append a VMOVSS instruction to the active function. +func (c *Context) VMOVSS(ops ...operand.Op) { + if inst, err := x86.VMOVSS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +// Construct and append a VMOVSS instruction to the active function. +// Operates on the global context. +func VMOVSS(ops ...operand.Op) { ctx.VMOVSS(ops...) } + +// 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 +// Construct and append a VMOVUPD instruction to the active function. +func (c *Context) VMOVUPD(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVUPD(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMOVUPD instruction to the active function. +// Operates on the global context. +func VMOVUPD(mxy, mxy1 operand.Op) { ctx.VMOVUPD(mxy, mxy1) } + +// 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 +// Construct and append a VMOVUPS instruction to the active function. +func (c *Context) VMOVUPS(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVUPS(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMOVUPS instruction to the active function. +// Operates on the global context. +func VMOVUPS(mxy, mxy1 operand.Op) { ctx.VMOVUPS(mxy, mxy1) } + +// 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 +// Construct and append a VMPSADBW instruction to the active function. +func (c *Context) VMPSADBW(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMPSADBW(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMPSADBW instruction to the active function. +// Operates on the global context. +func VMPSADBW(i, mxy, xy, xy1 operand.Op) { ctx.VMPSADBW(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VMULPD instruction to the active function. +func (c *Context) VMULPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMULPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMULPD instruction to the active function. +// Operates on the global context. +func VMULPD(mxy, xy, xy1 operand.Op) { ctx.VMULPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VMULPS instruction to the active function. +func (c *Context) VMULPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMULPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VMULPS instruction to the active function. +// Operates on the global context. +func VMULPS(mxy, xy, xy1 operand.Op) { ctx.VMULPS(mxy, xy, xy1) } + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +// Construct and append a VMULSD instruction to the active function. +func (c *Context) VMULSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMULSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +// Construct and append a VMULSD instruction to the active function. +// Operates on the global context. +func VMULSD(mx, x, x1 operand.Op) { ctx.VMULSD(mx, x, x1) } + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +// Construct and append a VMULSS instruction to the active function. +func (c *Context) VMULSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMULSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +// Construct and append a VMULSS instruction to the active function. +// Operates on the global context. +func VMULSS(mx, x, x1 operand.Op) { ctx.VMULSS(mx, x, x1) } + +// 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 +// Construct and append a VORPD instruction to the active function. +func (c *Context) VORPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VORPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VORPD instruction to the active function. +// Operates on the global context. +func VORPD(mxy, xy, xy1 operand.Op) { ctx.VORPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VORPS instruction to the active function. +func (c *Context) VORPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VORPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VORPS instruction to the active function. +// Operates on the global context. +func VORPS(mxy, xy, xy1 operand.Op) { ctx.VORPS(mxy, xy, xy1) } + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +// Construct and append a VPABSB instruction to the active function. +func (c *Context) VPABSB(mxy, xy operand.Op) { + if inst, err := x86.VPABSB(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +// Construct and append a VPABSB instruction to the active function. +// Operates on the global context. +func VPABSB(mxy, xy operand.Op) { ctx.VPABSB(mxy, xy) } + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +// Construct and append a VPABSD instruction to the active function. +func (c *Context) VPABSD(mxy, xy operand.Op) { + if inst, err := x86.VPABSD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +// Construct and append a VPABSD instruction to the active function. +// Operates on the global context. +func VPABSD(mxy, xy operand.Op) { ctx.VPABSD(mxy, xy) } + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +// Construct and append a VPABSW instruction to the active function. +func (c *Context) VPABSW(mxy, xy operand.Op) { + if inst, err := x86.VPABSW(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +// Construct and append a VPABSW instruction to the active function. +// Operates on the global context. +func VPABSW(mxy, xy operand.Op) { ctx.VPABSW(mxy, xy) } + +// 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 +// Construct and append a VPACKSSDW instruction to the active function. +func (c *Context) VPACKSSDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKSSDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPACKSSDW instruction to the active function. +// Operates on the global context. +func VPACKSSDW(mxy, xy, xy1 operand.Op) { ctx.VPACKSSDW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPACKSSWB instruction to the active function. +func (c *Context) VPACKSSWB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKSSWB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPACKSSWB instruction to the active function. +// Operates on the global context. +func VPACKSSWB(mxy, xy, xy1 operand.Op) { ctx.VPACKSSWB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPACKUSDW instruction to the active function. +func (c *Context) VPACKUSDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKUSDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPACKUSDW instruction to the active function. +// Operates on the global context. +func VPACKUSDW(mxy, xy, xy1 operand.Op) { ctx.VPACKUSDW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPACKUSWB instruction to the active function. +func (c *Context) VPACKUSWB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKUSWB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPACKUSWB instruction to the active function. +// Operates on the global context. +func VPACKUSWB(mxy, xy, xy1 operand.Op) { ctx.VPACKUSWB(mxy, xy, xy1) } + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +// Construct and append a VPADDB instruction to the active function. +func (c *Context) VPADDB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +// Construct and append a VPADDB instruction to the active function. +// Operates on the global context. +func VPADDB(mxy, xy, xy1 operand.Op) { ctx.VPADDB(mxy, xy, xy1) } + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +// Construct and append a VPADDD instruction to the active function. +func (c *Context) VPADDD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +// Construct and append a VPADDD instruction to the active function. +// Operates on the global context. +func VPADDD(mxy, xy, xy1 operand.Op) { ctx.VPADDD(mxy, xy, xy1) } + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +// Construct and append a VPADDQ instruction to the active function. +func (c *Context) VPADDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +// Construct and append a VPADDQ instruction to the active function. +// Operates on the global context. +func VPADDQ(mxy, xy, xy1 operand.Op) { ctx.VPADDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPADDSB instruction to the active function. +func (c *Context) VPADDSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPADDSB instruction to the active function. +// Operates on the global context. +func VPADDSB(mxy, xy, xy1 operand.Op) { ctx.VPADDSB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPADDSW instruction to the active function. +func (c *Context) VPADDSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPADDSW instruction to the active function. +// Operates on the global context. +func VPADDSW(mxy, xy, xy1 operand.Op) { ctx.VPADDSW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPADDUSB instruction to the active function. +func (c *Context) VPADDUSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDUSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPADDUSB instruction to the active function. +// Operates on the global context. +func VPADDUSB(mxy, xy, xy1 operand.Op) { ctx.VPADDUSB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPADDUSW instruction to the active function. +func (c *Context) VPADDUSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDUSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPADDUSW instruction to the active function. +// Operates on the global context. +func VPADDUSW(mxy, xy, xy1 operand.Op) { ctx.VPADDUSW(mxy, xy, xy1) } + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +// Construct and append a VPADDW instruction to the active function. +func (c *Context) VPADDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +// Construct and append a VPADDW instruction to the active function. +// Operates on the global context. +func VPADDW(mxy, xy, xy1 operand.Op) { ctx.VPADDW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPALIGNR instruction to the active function. +func (c *Context) VPALIGNR(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPALIGNR(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPALIGNR instruction to the active function. +// Operates on the global context. +func VPALIGNR(i, mxy, xy, xy1 operand.Op) { ctx.VPALIGNR(i, mxy, xy, xy1) } + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +// Construct and append a VPAND instruction to the active function. +func (c *Context) VPAND(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAND(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +// Construct and append a VPAND instruction to the active function. +// Operates on the global context. +func VPAND(mxy, xy, xy1 operand.Op) { ctx.VPAND(mxy, xy, xy1) } + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +// Construct and append a VPANDN instruction to the active function. +func (c *Context) VPANDN(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPANDN(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +// Construct and append a VPANDN instruction to the active function. +// Operates on the global context. +func VPANDN(mxy, xy, xy1 operand.Op) { ctx.VPANDN(mxy, xy, xy1) } + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +// Construct and append a VPAVGB instruction to the active function. +func (c *Context) VPAVGB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAVGB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +// Construct and append a VPAVGB instruction to the active function. +// Operates on the global context. +func VPAVGB(mxy, xy, xy1 operand.Op) { ctx.VPAVGB(mxy, xy, xy1) } + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +// Construct and append a VPAVGW instruction to the active function. +func (c *Context) VPAVGW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAVGW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +// Construct and append a VPAVGW instruction to the active function. +// Operates on the global context. +func VPAVGW(mxy, xy, xy1 operand.Op) { ctx.VPAVGW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPBLENDD instruction to the active function. +func (c *Context) VPBLENDD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPBLENDD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPBLENDD instruction to the active function. +// Operates on the global context. +func VPBLENDD(i, mxy, xy, xy1 operand.Op) { ctx.VPBLENDD(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VPBLENDVB instruction to the active function. +func (c *Context) VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VPBLENDVB(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPBLENDVB instruction to the active function. +// Operates on the global context. +func VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) { ctx.VPBLENDVB(xy, mxy, xy1, xy2) } + +// 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 +// Construct and append a VPBLENDW instruction to the active function. +func (c *Context) VPBLENDW(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPBLENDW(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPBLENDW instruction to the active function. +// Operates on the global context. +func VPBLENDW(i, mxy, xy, xy1 operand.Op) { ctx.VPBLENDW(i, mxy, xy, xy1) } + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +// Construct and append a VPBROADCASTB instruction to the active function. +func (c *Context) VPBROADCASTB(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTB(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +// Construct and append a VPBROADCASTB instruction to the active function. +// Operates on the global context. +func VPBROADCASTB(mx, xy operand.Op) { ctx.VPBROADCASTB(mx, xy) } + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +// Construct and append a VPBROADCASTD instruction to the active function. +func (c *Context) VPBROADCASTD(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +// Construct and append a VPBROADCASTD instruction to the active function. +// Operates on the global context. +func VPBROADCASTD(mx, xy operand.Op) { ctx.VPBROADCASTD(mx, xy) } + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +// Construct and append a VPBROADCASTQ instruction to the active function. +func (c *Context) VPBROADCASTQ(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +// Construct and append a VPBROADCASTQ instruction to the active function. +// Operates on the global context. +func VPBROADCASTQ(mx, xy operand.Op) { ctx.VPBROADCASTQ(mx, xy) } + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +// Construct and append a VPBROADCASTW instruction to the active function. +func (c *Context) VPBROADCASTW(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +// Construct and append a VPBROADCASTW instruction to the active function. +// Operates on the global context. +func VPBROADCASTW(mx, xy operand.Op) { ctx.VPBROADCASTW(mx, xy) } + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +// Construct and append a VPCLMULQDQ instruction to the active function. +func (c *Context) VPCLMULQDQ(i, mx, x, x1 operand.Op) { + if inst, err := x86.VPCLMULQDQ(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +// Construct and append a VPCLMULQDQ instruction to the active function. +// Operates on the global context. +func VPCLMULQDQ(i, mx, x, x1 operand.Op) { ctx.VPCLMULQDQ(i, mx, x, x1) } + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +// Construct and append a VPCMPEQB instruction to the active function. +func (c *Context) VPCMPEQB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +// Construct and append a VPCMPEQB instruction to the active function. +// Operates on the global context. +func VPCMPEQB(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQB(mxy, xy, xy1) } + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +// Construct and append a VPCMPEQD instruction to the active function. +func (c *Context) VPCMPEQD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +// Construct and append a VPCMPEQD instruction to the active function. +// Operates on the global context. +func VPCMPEQD(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQD(mxy, xy, xy1) } + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +// Construct and append a VPCMPEQQ instruction to the active function. +func (c *Context) VPCMPEQQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +// Construct and append a VPCMPEQQ instruction to the active function. +// Operates on the global context. +func VPCMPEQQ(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQQ(mxy, xy, xy1) } + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +// Construct and append a VPCMPEQW instruction to the active function. +func (c *Context) VPCMPEQW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +// Construct and append a VPCMPEQW instruction to the active function. +// Operates on the global context. +func VPCMPEQW(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQW(mxy, xy, xy1) } + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +// Construct and append a VPCMPESTRI instruction to the active function. +func (c *Context) VPCMPESTRI(i, mx, x operand.Op) { + if inst, err := x86.VPCMPESTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +// Construct and append a VPCMPESTRI instruction to the active function. +// Operates on the global context. +func VPCMPESTRI(i, mx, x operand.Op) { ctx.VPCMPESTRI(i, mx, x) } + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +// Construct and append a VPCMPESTRM instruction to the active function. +func (c *Context) VPCMPESTRM(i, mx, x operand.Op) { + if inst, err := x86.VPCMPESTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +// Construct and append a VPCMPESTRM instruction to the active function. +// Operates on the global context. +func VPCMPESTRM(i, mx, x operand.Op) { ctx.VPCMPESTRM(i, mx, x) } + +// 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 +// Construct and append a VPCMPGTB instruction to the active function. +func (c *Context) VPCMPGTB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPCMPGTB instruction to the active function. +// Operates on the global context. +func VPCMPGTB(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPCMPGTD instruction to the active function. +func (c *Context) VPCMPGTD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPCMPGTD instruction to the active function. +// Operates on the global context. +func VPCMPGTD(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTD(mxy, xy, xy1) } + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +// Construct and append a VPCMPGTQ instruction to the active function. +func (c *Context) VPCMPGTQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +// Construct and append a VPCMPGTQ instruction to the active function. +// Operates on the global context. +func VPCMPGTQ(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPCMPGTW instruction to the active function. +func (c *Context) VPCMPGTW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPCMPGTW instruction to the active function. +// Operates on the global context. +func VPCMPGTW(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTW(mxy, xy, xy1) } + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +// Construct and append a VPCMPISTRI instruction to the active function. +func (c *Context) VPCMPISTRI(i, mx, x operand.Op) { + if inst, err := x86.VPCMPISTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +// Construct and append a VPCMPISTRI instruction to the active function. +// Operates on the global context. +func VPCMPISTRI(i, mx, x operand.Op) { ctx.VPCMPISTRI(i, mx, x) } + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +// Construct and append a VPCMPISTRM instruction to the active function. +func (c *Context) VPCMPISTRM(i, mx, x operand.Op) { + if inst, err := x86.VPCMPISTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +// Construct and append a VPCMPISTRM instruction to the active function. +// Operates on the global context. +func VPCMPISTRM(i, mx, x operand.Op) { ctx.VPCMPISTRM(i, mx, x) } + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +// Construct and append a VPERM2F128 instruction to the active function. +func (c *Context) VPERM2F128(i, my, y, y1 operand.Op) { + if inst, err := x86.VPERM2F128(i, my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +// Construct and append a VPERM2F128 instruction to the active function. +// Operates on the global context. +func VPERM2F128(i, my, y, y1 operand.Op) { ctx.VPERM2F128(i, my, y, y1) } + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +// Construct and append a VPERM2I128 instruction to the active function. +func (c *Context) VPERM2I128(i, my, y, y1 operand.Op) { + if inst, err := x86.VPERM2I128(i, my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +// Construct and append a VPERM2I128 instruction to the active function. +// Operates on the global context. +func VPERM2I128(i, my, y, y1 operand.Op) { ctx.VPERM2I128(i, my, y, y1) } + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +// Construct and append a VPERMD instruction to the active function. +func (c *Context) VPERMD(my, y, y1 operand.Op) { + if inst, err := x86.VPERMD(my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +// Construct and append a VPERMD instruction to the active function. +// Operates on the global context. +func VPERMD(my, y, y1 operand.Op) { ctx.VPERMD(my, y, y1) } + +// 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 +// Construct and append a VPERMILPD instruction to the active function. +func (c *Context) VPERMILPD(imxy, mxy, xy operand.Op) { + if inst, err := x86.VPERMILPD(imxy, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPERMILPD instruction to the active function. +// Operates on the global context. +func VPERMILPD(imxy, mxy, xy operand.Op) { ctx.VPERMILPD(imxy, mxy, xy) } + +// 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 +// Construct and append a VPERMILPS instruction to the active function. +func (c *Context) VPERMILPS(imxy, mxy, xy operand.Op) { + if inst, err := x86.VPERMILPS(imxy, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPERMILPS instruction to the active function. +// Operates on the global context. +func VPERMILPS(imxy, mxy, xy operand.Op) { ctx.VPERMILPS(imxy, mxy, xy) } + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +// Construct and append a VPERMPD instruction to the active function. +func (c *Context) VPERMPD(i, my, y operand.Op) { + if inst, err := x86.VPERMPD(i, my, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +// Construct and append a VPERMPD instruction to the active function. +// Operates on the global context. +func VPERMPD(i, my, y operand.Op) { ctx.VPERMPD(i, my, y) } + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +// Construct and append a VPERMPS instruction to the active function. +func (c *Context) VPERMPS(my, y, y1 operand.Op) { + if inst, err := x86.VPERMPS(my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +// Construct and append a VPERMPS instruction to the active function. +// Operates on the global context. +func VPERMPS(my, y, y1 operand.Op) { ctx.VPERMPS(my, y, y1) } + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +// Construct and append a VPERMQ instruction to the active function. +func (c *Context) VPERMQ(i, my, y operand.Op) { + if inst, err := x86.VPERMQ(i, my, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +// Construct and append a VPERMQ instruction to the active function. +// Operates on the global context. +func VPERMQ(i, my, y operand.Op) { ctx.VPERMQ(i, my, y) } + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +// Construct and append a VPEXTRB instruction to the active function. +func (c *Context) VPEXTRB(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRB(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +// Construct and append a VPEXTRB instruction to the active function. +// Operates on the global context. +func VPEXTRB(i, x, mr operand.Op) { ctx.VPEXTRB(i, x, mr) } + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +// Construct and append a VPEXTRD instruction to the active function. +func (c *Context) VPEXTRD(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRD(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +// Construct and append a VPEXTRD instruction to the active function. +// Operates on the global context. +func VPEXTRD(i, x, mr operand.Op) { ctx.VPEXTRD(i, x, mr) } + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +// Construct and append a VPEXTRQ instruction to the active function. +func (c *Context) VPEXTRQ(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRQ(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +// Construct and append a VPEXTRQ instruction to the active function. +// Operates on the global context. +func VPEXTRQ(i, x, mr operand.Op) { ctx.VPEXTRQ(i, x, mr) } + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +// Construct and append a VPEXTRW instruction to the active function. +func (c *Context) VPEXTRW(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRW(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +// Construct and append a VPEXTRW instruction to the active function. +// Operates on the global context. +func VPEXTRW(i, x, mr operand.Op) { ctx.VPEXTRW(i, x, mr) } + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +// Construct and append a VPGATHERDD instruction to the active function. +func (c *Context) VPGATHERDD(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERDD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +// Construct and append a VPGATHERDD instruction to the active function. +// Operates on the global context. +func VPGATHERDD(xy, v, xy1 operand.Op) { ctx.VPGATHERDD(xy, v, xy1) } + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +// Construct and append a VPGATHERDQ instruction to the active function. +func (c *Context) VPGATHERDQ(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERDQ(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +// Construct and append a VPGATHERDQ instruction to the active function. +// Operates on the global context. +func VPGATHERDQ(xy, v, xy1 operand.Op) { ctx.VPGATHERDQ(xy, v, xy1) } + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +// Construct and append a VPGATHERQD instruction to the active function. +func (c *Context) VPGATHERQD(x, v, x1 operand.Op) { + if inst, err := x86.VPGATHERQD(x, v, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +// Construct and append a VPGATHERQD instruction to the active function. +// Operates on the global context. +func VPGATHERQD(x, v, x1 operand.Op) { ctx.VPGATHERQD(x, v, x1) } + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +// Construct and append a VPGATHERQQ instruction to the active function. +func (c *Context) VPGATHERQQ(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERQQ(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +// Construct and append a VPGATHERQQ instruction to the active function. +// Operates on the global context. +func VPGATHERQQ(xy, v, xy1 operand.Op) { ctx.VPGATHERQQ(xy, v, xy1) } + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +// Construct and append a VPHADDD instruction to the active function. +func (c *Context) VPHADDD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +// Construct and append a VPHADDD instruction to the active function. +// Operates on the global context. +func VPHADDD(mxy, xy, xy1 operand.Op) { ctx.VPHADDD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPHADDSW instruction to the active function. +func (c *Context) VPHADDSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPHADDSW instruction to the active function. +// Operates on the global context. +func VPHADDSW(mxy, xy, xy1 operand.Op) { ctx.VPHADDSW(mxy, xy, xy1) } + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +// Construct and append a VPHADDW instruction to the active function. +func (c *Context) VPHADDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +// Construct and append a VPHADDW instruction to the active function. +// Operates on the global context. +func VPHADDW(mxy, xy, xy1 operand.Op) { ctx.VPHADDW(mxy, xy, xy1) } + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +// Construct and append a VPHMINPOSUW instruction to the active function. +func (c *Context) VPHMINPOSUW(mx, x operand.Op) { + if inst, err := x86.VPHMINPOSUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +// Construct and append a VPHMINPOSUW instruction to the active function. +// Operates on the global context. +func VPHMINPOSUW(mx, x operand.Op) { ctx.VPHMINPOSUW(mx, x) } + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +// Construct and append a VPHSUBD instruction to the active function. +func (c *Context) VPHSUBD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +// Construct and append a VPHSUBD instruction to the active function. +// Operates on the global context. +func VPHSUBD(mxy, xy, xy1 operand.Op) { ctx.VPHSUBD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPHSUBSW instruction to the active function. +func (c *Context) VPHSUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPHSUBSW instruction to the active function. +// Operates on the global context. +func VPHSUBSW(mxy, xy, xy1 operand.Op) { ctx.VPHSUBSW(mxy, xy, xy1) } + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +// Construct and append a VPHSUBW instruction to the active function. +func (c *Context) VPHSUBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +// Construct and append a VPHSUBW instruction to the active function. +// Operates on the global context. +func VPHSUBW(mxy, xy, xy1 operand.Op) { ctx.VPHSUBW(mxy, xy, xy1) } + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +// Construct and append a VPINSRB instruction to the active function. +func (c *Context) VPINSRB(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRB(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +// Construct and append a VPINSRB instruction to the active function. +// Operates on the global context. +func VPINSRB(i, mr, x, x1 operand.Op) { ctx.VPINSRB(i, mr, x, x1) } + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +// Construct and append a VPINSRD instruction to the active function. +func (c *Context) VPINSRD(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRD(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +// Construct and append a VPINSRD instruction to the active function. +// Operates on the global context. +func VPINSRD(i, mr, x, x1 operand.Op) { ctx.VPINSRD(i, mr, x, x1) } + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +// Construct and append a VPINSRQ instruction to the active function. +func (c *Context) VPINSRQ(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRQ(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +// Construct and append a VPINSRQ instruction to the active function. +// Operates on the global context. +func VPINSRQ(i, mr, x, x1 operand.Op) { ctx.VPINSRQ(i, mr, x, x1) } + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +// Construct and append a VPINSRW instruction to the active function. +func (c *Context) VPINSRW(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRW(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +// Construct and append a VPINSRW instruction to the active function. +// Operates on the global context. +func VPINSRW(i, mr, x, x1 operand.Op) { ctx.VPINSRW(i, mr, x, x1) } + +// 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 +// Construct and append a VPMADDUBSW instruction to the active function. +func (c *Context) VPMADDUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMADDUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMADDUBSW instruction to the active function. +// Operates on the global context. +func VPMADDUBSW(mxy, xy, xy1 operand.Op) { ctx.VPMADDUBSW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMADDWD instruction to the active function. +func (c *Context) VPMADDWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMADDWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMADDWD instruction to the active function. +// Operates on the global context. +func VPMADDWD(mxy, xy, xy1 operand.Op) { ctx.VPMADDWD(mxy, xy, xy1) } + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +// Construct and append a VPMASKMOVD instruction to the active function. +func (c *Context) VPMASKMOVD(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VPMASKMOVD(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +// Construct and append a VPMASKMOVD instruction to the active function. +// Operates on the global context. +func VPMASKMOVD(mxy, xy, mxy1 operand.Op) { ctx.VPMASKMOVD(mxy, xy, mxy1) } + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +// Construct and append a VPMASKMOVQ instruction to the active function. +func (c *Context) VPMASKMOVQ(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VPMASKMOVQ(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +// Construct and append a VPMASKMOVQ instruction to the active function. +// Operates on the global context. +func VPMASKMOVQ(mxy, xy, mxy1 operand.Op) { ctx.VPMASKMOVQ(mxy, xy, mxy1) } + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +// Construct and append a VPMAXSB instruction to the active function. +func (c *Context) VPMAXSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +// Construct and append a VPMAXSB instruction to the active function. +// Operates on the global context. +func VPMAXSB(mxy, xy, xy1 operand.Op) { ctx.VPMAXSB(mxy, xy, xy1) } + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +// Construct and append a VPMAXSD instruction to the active function. +func (c *Context) VPMAXSD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +// Construct and append a VPMAXSD instruction to the active function. +// Operates on the global context. +func VPMAXSD(mxy, xy, xy1 operand.Op) { ctx.VPMAXSD(mxy, xy, xy1) } + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +// Construct and append a VPMAXSW instruction to the active function. +func (c *Context) VPMAXSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +// Construct and append a VPMAXSW instruction to the active function. +// Operates on the global context. +func VPMAXSW(mxy, xy, xy1 operand.Op) { ctx.VPMAXSW(mxy, xy, xy1) } + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +// Construct and append a VPMAXUB instruction to the active function. +func (c *Context) VPMAXUB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +// Construct and append a VPMAXUB instruction to the active function. +// Operates on the global context. +func VPMAXUB(mxy, xy, xy1 operand.Op) { ctx.VPMAXUB(mxy, xy, xy1) } + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +// Construct and append a VPMAXUD instruction to the active function. +func (c *Context) VPMAXUD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +// Construct and append a VPMAXUD instruction to the active function. +// Operates on the global context. +func VPMAXUD(mxy, xy, xy1 operand.Op) { ctx.VPMAXUD(mxy, xy, xy1) } + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +// Construct and append a VPMAXUW instruction to the active function. +func (c *Context) VPMAXUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +// Construct and append a VPMAXUW instruction to the active function. +// Operates on the global context. +func VPMAXUW(mxy, xy, xy1 operand.Op) { ctx.VPMAXUW(mxy, xy, xy1) } + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +// Construct and append a VPMINSB instruction to the active function. +func (c *Context) VPMINSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +// Construct and append a VPMINSB instruction to the active function. +// Operates on the global context. +func VPMINSB(mxy, xy, xy1 operand.Op) { ctx.VPMINSB(mxy, xy, xy1) } + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +// Construct and append a VPMINSD instruction to the active function. +func (c *Context) VPMINSD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +// Construct and append a VPMINSD instruction to the active function. +// Operates on the global context. +func VPMINSD(mxy, xy, xy1 operand.Op) { ctx.VPMINSD(mxy, xy, xy1) } + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +// Construct and append a VPMINSW instruction to the active function. +func (c *Context) VPMINSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +// Construct and append a VPMINSW instruction to the active function. +// Operates on the global context. +func VPMINSW(mxy, xy, xy1 operand.Op) { ctx.VPMINSW(mxy, xy, xy1) } + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +// Construct and append a VPMINUB instruction to the active function. +func (c *Context) VPMINUB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +// Construct and append a VPMINUB instruction to the active function. +// Operates on the global context. +func VPMINUB(mxy, xy, xy1 operand.Op) { ctx.VPMINUB(mxy, xy, xy1) } + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +// Construct and append a VPMINUD instruction to the active function. +func (c *Context) VPMINUD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +// Construct and append a VPMINUD instruction to the active function. +// Operates on the global context. +func VPMINUD(mxy, xy, xy1 operand.Op) { ctx.VPMINUD(mxy, xy, xy1) } + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +// Construct and append a VPMINUW instruction to the active function. +func (c *Context) VPMINUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +// Construct and append a VPMINUW instruction to the active function. +// Operates on the global context. +func VPMINUW(mxy, xy, xy1 operand.Op) { ctx.VPMINUW(mxy, xy, xy1) } + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +// Construct and append a VPMOVMSKB instruction to the active function. +func (c *Context) VPMOVMSKB(xy, r operand.Op) { + if inst, err := x86.VPMOVMSKB(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +// Construct and append a VPMOVMSKB instruction to the active function. +// Operates on the global context. +func VPMOVMSKB(xy, r operand.Op) { ctx.VPMOVMSKB(xy, r) } + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +// Construct and append a VPMOVSXBD instruction to the active function. +func (c *Context) VPMOVSXBD(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +// Construct and append a VPMOVSXBD instruction to the active function. +// Operates on the global context. +func VPMOVSXBD(mx, xy operand.Op) { ctx.VPMOVSXBD(mx, xy) } + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +// Construct and append a VPMOVSXBQ instruction to the active function. +func (c *Context) VPMOVSXBQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +// Construct and append a VPMOVSXBQ instruction to the active function. +// Operates on the global context. +func VPMOVSXBQ(mx, xy operand.Op) { ctx.VPMOVSXBQ(mx, xy) } + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +// Construct and append a VPMOVSXBW instruction to the active function. +func (c *Context) VPMOVSXBW(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +// Construct and append a VPMOVSXBW instruction to the active function. +// Operates on the global context. +func VPMOVSXBW(mx, xy operand.Op) { ctx.VPMOVSXBW(mx, xy) } + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +// Construct and append a VPMOVSXDQ instruction to the active function. +func (c *Context) VPMOVSXDQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXDQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +// Construct and append a VPMOVSXDQ instruction to the active function. +// Operates on the global context. +func VPMOVSXDQ(mx, xy operand.Op) { ctx.VPMOVSXDQ(mx, xy) } + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +// Construct and append a VPMOVSXWD instruction to the active function. +func (c *Context) VPMOVSXWD(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXWD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +// Construct and append a VPMOVSXWD instruction to the active function. +// Operates on the global context. +func VPMOVSXWD(mx, xy operand.Op) { ctx.VPMOVSXWD(mx, xy) } + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +// Construct and append a VPMOVSXWQ instruction to the active function. +func (c *Context) VPMOVSXWQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXWQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +// Construct and append a VPMOVSXWQ instruction to the active function. +// Operates on the global context. +func VPMOVSXWQ(mx, xy operand.Op) { ctx.VPMOVSXWQ(mx, xy) } + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +// Construct and append a VPMOVZXBD instruction to the active function. +func (c *Context) VPMOVZXBD(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +// Construct and append a VPMOVZXBD instruction to the active function. +// Operates on the global context. +func VPMOVZXBD(mx, xy operand.Op) { ctx.VPMOVZXBD(mx, xy) } + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +// Construct and append a VPMOVZXBQ instruction to the active function. +func (c *Context) VPMOVZXBQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +// Construct and append a VPMOVZXBQ instruction to the active function. +// Operates on the global context. +func VPMOVZXBQ(mx, xy operand.Op) { ctx.VPMOVZXBQ(mx, xy) } + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +// Construct and append a VPMOVZXBW instruction to the active function. +func (c *Context) VPMOVZXBW(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +// Construct and append a VPMOVZXBW instruction to the active function. +// Operates on the global context. +func VPMOVZXBW(mx, xy operand.Op) { ctx.VPMOVZXBW(mx, xy) } + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +// Construct and append a VPMOVZXDQ instruction to the active function. +func (c *Context) VPMOVZXDQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXDQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +// Construct and append a VPMOVZXDQ instruction to the active function. +// Operates on the global context. +func VPMOVZXDQ(mx, xy operand.Op) { ctx.VPMOVZXDQ(mx, xy) } + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +// Construct and append a VPMOVZXWD instruction to the active function. +func (c *Context) VPMOVZXWD(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXWD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +// Construct and append a VPMOVZXWD instruction to the active function. +// Operates on the global context. +func VPMOVZXWD(mx, xy operand.Op) { ctx.VPMOVZXWD(mx, xy) } + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +// Construct and append a VPMOVZXWQ instruction to the active function. +func (c *Context) VPMOVZXWQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXWQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +// Construct and append a VPMOVZXWQ instruction to the active function. +// Operates on the global context. +func VPMOVZXWQ(mx, xy operand.Op) { ctx.VPMOVZXWQ(mx, xy) } + +// 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 +// Construct and append a VPMULDQ instruction to the active function. +func (c *Context) VPMULDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULDQ instruction to the active function. +// Operates on the global context. +func VPMULDQ(mxy, xy, xy1 operand.Op) { ctx.VPMULDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMULHRSW instruction to the active function. +func (c *Context) VPMULHRSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHRSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULHRSW instruction to the active function. +// Operates on the global context. +func VPMULHRSW(mxy, xy, xy1 operand.Op) { ctx.VPMULHRSW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMULHUW instruction to the active function. +func (c *Context) VPMULHUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULHUW instruction to the active function. +// Operates on the global context. +func VPMULHUW(mxy, xy, xy1 operand.Op) { ctx.VPMULHUW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMULHW instruction to the active function. +func (c *Context) VPMULHW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULHW instruction to the active function. +// Operates on the global context. +func VPMULHW(mxy, xy, xy1 operand.Op) { ctx.VPMULHW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMULLD instruction to the active function. +func (c *Context) VPMULLD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULLD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULLD instruction to the active function. +// Operates on the global context. +func VPMULLD(mxy, xy, xy1 operand.Op) { ctx.VPMULLD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPMULLW instruction to the active function. +func (c *Context) VPMULLW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULLW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPMULLW instruction to the active function. +// Operates on the global context. +func VPMULLW(mxy, xy, xy1 operand.Op) { ctx.VPMULLW(mxy, xy, xy1) } + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +// Construct and append a VPMULUDQ instruction to the active function. +func (c *Context) VPMULUDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULUDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +// Construct and append a VPMULUDQ instruction to the active function. +// Operates on the global context. +func VPMULUDQ(mxy, xy, xy1 operand.Op) { ctx.VPMULUDQ(mxy, xy, xy1) } + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +// Construct and append a VPOR instruction to the active function. +func (c *Context) VPOR(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPOR(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +// Construct and append a VPOR instruction to the active function. +// Operates on the global context. +func VPOR(mxy, xy, xy1 operand.Op) { ctx.VPOR(mxy, xy, xy1) } + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +// Construct and append a VPSADBW instruction to the active function. +func (c *Context) VPSADBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSADBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +// Construct and append a VPSADBW instruction to the active function. +// Operates on the global context. +func VPSADBW(mxy, xy, xy1 operand.Op) { ctx.VPSADBW(mxy, xy, xy1) } + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +// Construct and append a VPSHUFB instruction to the active function. +func (c *Context) VPSHUFB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSHUFB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +// Construct and append a VPSHUFB instruction to the active function. +// Operates on the global context. +func VPSHUFB(mxy, xy, xy1 operand.Op) { ctx.VPSHUFB(mxy, xy, xy1) } + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +// Construct and append a VPSHUFD instruction to the active function. +func (c *Context) VPSHUFD(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFD(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +// Construct and append a VPSHUFD instruction to the active function. +// Operates on the global context. +func VPSHUFD(i, mxy, xy operand.Op) { ctx.VPSHUFD(i, mxy, xy) } + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +// Construct and append a VPSHUFHW instruction to the active function. +func (c *Context) VPSHUFHW(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFHW(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +// Construct and append a VPSHUFHW instruction to the active function. +// Operates on the global context. +func VPSHUFHW(i, mxy, xy operand.Op) { ctx.VPSHUFHW(i, mxy, xy) } + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +// Construct and append a VPSHUFLW instruction to the active function. +func (c *Context) VPSHUFLW(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFLW(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +// Construct and append a VPSHUFLW instruction to the active function. +// Operates on the global context. +func VPSHUFLW(i, mxy, xy operand.Op) { ctx.VPSHUFLW(i, mxy, xy) } + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +// Construct and append a VPSIGNB instruction to the active function. +func (c *Context) VPSIGNB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGNB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +// Construct and append a VPSIGNB instruction to the active function. +// Operates on the global context. +func VPSIGNB(mxy, xy, xy1 operand.Op) { ctx.VPSIGNB(mxy, xy, xy1) } + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +// Construct and append a VPSIGND instruction to the active function. +func (c *Context) VPSIGND(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGND(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +// Construct and append a VPSIGND instruction to the active function. +// Operates on the global context. +func VPSIGND(mxy, xy, xy1 operand.Op) { ctx.VPSIGND(mxy, xy, xy1) } + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +// Construct and append a VPSIGNW instruction to the active function. +func (c *Context) VPSIGNW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGNW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +// Construct and append a VPSIGNW instruction to the active function. +// Operates on the global context. +func VPSIGNW(mxy, xy, xy1 operand.Op) { ctx.VPSIGNW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSLLD instruction to the active function. +func (c *Context) VPSLLD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSLLD instruction to the active function. +// Operates on the global context. +func VPSLLD(imx, xy, xy1 operand.Op) { ctx.VPSLLD(imx, xy, xy1) } + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +// Construct and append a VPSLLDQ instruction to the active function. +func (c *Context) VPSLLDQ(i, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLDQ(i, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +// Construct and append a VPSLLDQ instruction to the active function. +// Operates on the global context. +func VPSLLDQ(i, xy, xy1 operand.Op) { ctx.VPSLLDQ(i, xy, xy1) } + +// 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 +// Construct and append a VPSLLQ instruction to the active function. +func (c *Context) VPSLLQ(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLQ(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSLLQ instruction to the active function. +// Operates on the global context. +func VPSLLQ(imx, xy, xy1 operand.Op) { ctx.VPSLLQ(imx, xy, xy1) } + +// 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 +// Construct and append a VPSLLVD instruction to the active function. +func (c *Context) VPSLLVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSLLVD instruction to the active function. +// Operates on the global context. +func VPSLLVD(mxy, xy, xy1 operand.Op) { ctx.VPSLLVD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSLLVQ instruction to the active function. +func (c *Context) VPSLLVQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLVQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSLLVQ instruction to the active function. +// Operates on the global context. +func VPSLLVQ(mxy, xy, xy1 operand.Op) { ctx.VPSLLVQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSLLW instruction to the active function. +func (c *Context) VPSLLW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSLLW instruction to the active function. +// Operates on the global context. +func VPSLLW(imx, xy, xy1 operand.Op) { ctx.VPSLLW(imx, xy, xy1) } + +// 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 +// Construct and append a VPSRAD instruction to the active function. +func (c *Context) VPSRAD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRAD instruction to the active function. +// Operates on the global context. +func VPSRAD(imx, xy, xy1 operand.Op) { ctx.VPSRAD(imx, xy, xy1) } + +// 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 +// Construct and append a VPSRAVD instruction to the active function. +func (c *Context) VPSRAVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRAVD instruction to the active function. +// Operates on the global context. +func VPSRAVD(mxy, xy, xy1 operand.Op) { ctx.VPSRAVD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSRAW instruction to the active function. +func (c *Context) VPSRAW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRAW instruction to the active function. +// Operates on the global context. +func VPSRAW(imx, xy, xy1 operand.Op) { ctx.VPSRAW(imx, xy, xy1) } + +// 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 +// Construct and append a VPSRLD instruction to the active function. +func (c *Context) VPSRLD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRLD instruction to the active function. +// Operates on the global context. +func VPSRLD(imx, xy, xy1 operand.Op) { ctx.VPSRLD(imx, xy, xy1) } + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +// Construct and append a VPSRLDQ instruction to the active function. +func (c *Context) VPSRLDQ(i, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLDQ(i, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +// Construct and append a VPSRLDQ instruction to the active function. +// Operates on the global context. +func VPSRLDQ(i, xy, xy1 operand.Op) { ctx.VPSRLDQ(i, xy, xy1) } + +// 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 +// Construct and append a VPSRLQ instruction to the active function. +func (c *Context) VPSRLQ(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLQ(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRLQ instruction to the active function. +// Operates on the global context. +func VPSRLQ(imx, xy, xy1 operand.Op) { ctx.VPSRLQ(imx, xy, xy1) } + +// 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 +// Construct and append a VPSRLVD instruction to the active function. +func (c *Context) VPSRLVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRLVD instruction to the active function. +// Operates on the global context. +func VPSRLVD(mxy, xy, xy1 operand.Op) { ctx.VPSRLVD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSRLVQ instruction to the active function. +func (c *Context) VPSRLVQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLVQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRLVQ instruction to the active function. +// Operates on the global context. +func VPSRLVQ(mxy, xy, xy1 operand.Op) { ctx.VPSRLVQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSRLW instruction to the active function. +func (c *Context) VPSRLW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSRLW instruction to the active function. +// Operates on the global context. +func VPSRLW(imx, xy, xy1 operand.Op) { ctx.VPSRLW(imx, xy, xy1) } + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +// Construct and append a VPSUBB instruction to the active function. +func (c *Context) VPSUBB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +// Construct and append a VPSUBB instruction to the active function. +// Operates on the global context. +func VPSUBB(mxy, xy, xy1 operand.Op) { ctx.VPSUBB(mxy, xy, xy1) } + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +// Construct and append a VPSUBD instruction to the active function. +func (c *Context) VPSUBD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +// Construct and append a VPSUBD instruction to the active function. +// Operates on the global context. +func VPSUBD(mxy, xy, xy1 operand.Op) { ctx.VPSUBD(mxy, xy, xy1) } + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +// Construct and append a VPSUBQ instruction to the active function. +func (c *Context) VPSUBQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +// Construct and append a VPSUBQ instruction to the active function. +// Operates on the global context. +func VPSUBQ(mxy, xy, xy1 operand.Op) { ctx.VPSUBQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSUBSB instruction to the active function. +func (c *Context) VPSUBSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSUBSB instruction to the active function. +// Operates on the global context. +func VPSUBSB(mxy, xy, xy1 operand.Op) { ctx.VPSUBSB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSUBSW instruction to the active function. +func (c *Context) VPSUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSUBSW instruction to the active function. +// Operates on the global context. +func VPSUBSW(mxy, xy, xy1 operand.Op) { ctx.VPSUBSW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSUBUSB instruction to the active function. +func (c *Context) VPSUBUSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBUSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSUBUSB instruction to the active function. +// Operates on the global context. +func VPSUBUSB(mxy, xy, xy1 operand.Op) { ctx.VPSUBUSB(mxy, xy, xy1) } + +// 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 +// Construct and append a VPSUBUSW instruction to the active function. +func (c *Context) VPSUBUSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBUSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPSUBUSW instruction to the active function. +// Operates on the global context. +func VPSUBUSW(mxy, xy, xy1 operand.Op) { ctx.VPSUBUSW(mxy, xy, xy1) } + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +// Construct and append a VPSUBW instruction to the active function. +func (c *Context) VPSUBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +// Construct and append a VPSUBW instruction to the active function. +// Operates on the global context. +func VPSUBW(mxy, xy, xy1 operand.Op) { ctx.VPSUBW(mxy, xy, xy1) } + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +// Construct and append a VPTEST instruction to the active function. +func (c *Context) VPTEST(mxy, xy operand.Op) { + if inst, err := x86.VPTEST(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +// Construct and append a VPTEST instruction to the active function. +// Operates on the global context. +func VPTEST(mxy, xy operand.Op) { ctx.VPTEST(mxy, xy) } + +// 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 +// Construct and append a VPUNPCKHBW instruction to the active function. +func (c *Context) VPUNPCKHBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKHBW instruction to the active function. +// Operates on the global context. +func VPUNPCKHBW(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHBW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKHDQ instruction to the active function. +func (c *Context) VPUNPCKHDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKHDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKHDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKHQDQ instruction to the active function. +func (c *Context) VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHQDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKHQDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHQDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKHWD instruction to the active function. +func (c *Context) VPUNPCKHWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKHWD instruction to the active function. +// Operates on the global context. +func VPUNPCKHWD(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHWD(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKLBW instruction to the active function. +func (c *Context) VPUNPCKLBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKLBW instruction to the active function. +// Operates on the global context. +func VPUNPCKLBW(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLBW(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKLDQ instruction to the active function. +func (c *Context) VPUNPCKLDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKLDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKLDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKLQDQ instruction to the active function. +func (c *Context) VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLQDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKLQDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLQDQ(mxy, xy, xy1) } + +// 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 +// Construct and append a VPUNPCKLWD instruction to the active function. +func (c *Context) VPUNPCKLWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VPUNPCKLWD instruction to the active function. +// Operates on the global context. +func VPUNPCKLWD(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLWD(mxy, xy, xy1) } + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +// Construct and append a VPXOR instruction to the active function. +func (c *Context) VPXOR(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPXOR(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +// Construct and append a VPXOR instruction to the active function. +// Operates on the global context. +func VPXOR(mxy, xy, xy1 operand.Op) { ctx.VPXOR(mxy, xy, xy1) } + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +// Construct and append a VRCPPS instruction to the active function. +func (c *Context) VRCPPS(mxy, xy operand.Op) { + if inst, err := x86.VRCPPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +// Construct and append a VRCPPS instruction to the active function. +// Operates on the global context. +func VRCPPS(mxy, xy operand.Op) { ctx.VRCPPS(mxy, xy) } + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +// Construct and append a VRCPSS instruction to the active function. +func (c *Context) VRCPSS(mx, x, x1 operand.Op) { + if inst, err := x86.VRCPSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +// Construct and append a VRCPSS instruction to the active function. +// Operates on the global context. +func VRCPSS(mx, x, x1 operand.Op) { ctx.VRCPSS(mx, x, x1) } + +// 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 +// Construct and append a VROUNDPD instruction to the active function. +func (c *Context) VROUNDPD(i, mxy, xy operand.Op) { + if inst, err := x86.VROUNDPD(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VROUNDPD instruction to the active function. +// Operates on the global context. +func VROUNDPD(i, mxy, xy operand.Op) { ctx.VROUNDPD(i, mxy, xy) } + +// 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 +// Construct and append a VROUNDPS instruction to the active function. +func (c *Context) VROUNDPS(i, mxy, xy operand.Op) { + if inst, err := x86.VROUNDPS(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VROUNDPS instruction to the active function. +// Operates on the global context. +func VROUNDPS(i, mxy, xy operand.Op) { ctx.VROUNDPS(i, mxy, xy) } + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +// Construct and append a VROUNDSD instruction to the active function. +func (c *Context) VROUNDSD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VROUNDSD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +// Construct and append a VROUNDSD instruction to the active function. +// Operates on the global context. +func VROUNDSD(i, mx, x, x1 operand.Op) { ctx.VROUNDSD(i, mx, x, x1) } + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +// Construct and append a VROUNDSS instruction to the active function. +func (c *Context) VROUNDSS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VROUNDSS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +// Construct and append a VROUNDSS instruction to the active function. +// Operates on the global context. +func VROUNDSS(i, mx, x, x1 operand.Op) { ctx.VROUNDSS(i, mx, x, x1) } + +// 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 +// Construct and append a VRSQRTPS instruction to the active function. +func (c *Context) VRSQRTPS(mxy, xy operand.Op) { + if inst, err := x86.VRSQRTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VRSQRTPS instruction to the active function. +// Operates on the global context. +func VRSQRTPS(mxy, xy operand.Op) { ctx.VRSQRTPS(mxy, xy) } + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +// Construct and append a VRSQRTSS instruction to the active function. +func (c *Context) VRSQRTSS(mx, x, x1 operand.Op) { + if inst, err := x86.VRSQRTSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +// Construct and append a VRSQRTSS instruction to the active function. +// Operates on the global context. +func VRSQRTSS(mx, x, x1 operand.Op) { ctx.VRSQRTSS(mx, x, x1) } + +// 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 +// Construct and append a VSHUFPD instruction to the active function. +func (c *Context) VSHUFPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSHUFPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VSHUFPD instruction to the active function. +// Operates on the global context. +func VSHUFPD(i, mxy, xy, xy1 operand.Op) { ctx.VSHUFPD(i, mxy, xy, xy1) } + +// 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 +// Construct and append a VSHUFPS instruction to the active function. +func (c *Context) VSHUFPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSHUFPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VSHUFPS instruction to the active function. +// Operates on the global context. +func VSHUFPS(i, mxy, xy, xy1 operand.Op) { ctx.VSHUFPS(i, mxy, xy, xy1) } + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +// Construct and append a VSQRTPD instruction to the active function. +func (c *Context) VSQRTPD(mxy, xy operand.Op) { + if inst, err := x86.VSQRTPD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +// Construct and append a VSQRTPD instruction to the active function. +// Operates on the global context. +func VSQRTPD(mxy, xy operand.Op) { ctx.VSQRTPD(mxy, xy) } + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +// Construct and append a VSQRTPS instruction to the active function. +func (c *Context) VSQRTPS(mxy, xy operand.Op) { + if inst, err := x86.VSQRTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +// Construct and append a VSQRTPS instruction to the active function. +// Operates on the global context. +func VSQRTPS(mxy, xy operand.Op) { ctx.VSQRTPS(mxy, xy) } + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +// Construct and append a VSQRTSD instruction to the active function. +func (c *Context) VSQRTSD(mx, x, x1 operand.Op) { + if inst, err := x86.VSQRTSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +// Construct and append a VSQRTSD instruction to the active function. +// Operates on the global context. +func VSQRTSD(mx, x, x1 operand.Op) { ctx.VSQRTSD(mx, x, x1) } + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +// Construct and append a VSQRTSS instruction to the active function. +func (c *Context) VSQRTSS(mx, x, x1 operand.Op) { + if inst, err := x86.VSQRTSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +// Construct and append a VSQRTSS instruction to the active function. +// Operates on the global context. +func VSQRTSS(mx, x, x1 operand.Op) { ctx.VSQRTSS(mx, x, x1) } + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +// Construct and append a VSTMXCSR instruction to the active function. +func (c *Context) VSTMXCSR(m operand.Op) { + if inst, err := x86.VSTMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +// Construct and append a VSTMXCSR instruction to the active function. +// Operates on the global context. +func VSTMXCSR(m operand.Op) { ctx.VSTMXCSR(m) } + +// 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 +// Construct and append a VSUBPD instruction to the active function. +func (c *Context) VSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VSUBPD instruction to the active function. +// Operates on the global context. +func VSUBPD(mxy, xy, xy1 operand.Op) { ctx.VSUBPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VSUBPS instruction to the active function. +func (c *Context) VSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VSUBPS instruction to the active function. +// Operates on the global context. +func VSUBPS(mxy, xy, xy1 operand.Op) { ctx.VSUBPS(mxy, xy, xy1) } + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +// Construct and append a VSUBSD instruction to the active function. +func (c *Context) VSUBSD(mx, x, x1 operand.Op) { + if inst, err := x86.VSUBSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +// Construct and append a VSUBSD instruction to the active function. +// Operates on the global context. +func VSUBSD(mx, x, x1 operand.Op) { ctx.VSUBSD(mx, x, x1) } + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +// Construct and append a VSUBSS instruction to the active function. +func (c *Context) VSUBSS(mx, x, x1 operand.Op) { + if inst, err := x86.VSUBSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +// Construct and append a VSUBSS instruction to the active function. +// Operates on the global context. +func VSUBSS(mx, x, x1 operand.Op) { ctx.VSUBSS(mx, x, x1) } + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +// Construct and append a VTESTPD instruction to the active function. +func (c *Context) VTESTPD(mxy, xy operand.Op) { + if inst, err := x86.VTESTPD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +// Construct and append a VTESTPD instruction to the active function. +// Operates on the global context. +func VTESTPD(mxy, xy operand.Op) { ctx.VTESTPD(mxy, xy) } + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +// Construct and append a VTESTPS instruction to the active function. +func (c *Context) VTESTPS(mxy, xy operand.Op) { + if inst, err := x86.VTESTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +// Construct and append a VTESTPS instruction to the active function. +// Operates on the global context. +func VTESTPS(mxy, xy operand.Op) { ctx.VTESTPS(mxy, xy) } + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +// Construct and append a VUCOMISD instruction to the active function. +func (c *Context) VUCOMISD(mx, x operand.Op) { + if inst, err := x86.VUCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +// Construct and append a VUCOMISD instruction to the active function. +// Operates on the global context. +func VUCOMISD(mx, x operand.Op) { ctx.VUCOMISD(mx, x) } + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +// Construct and append a VUCOMISS instruction to the active function. +func (c *Context) VUCOMISS(mx, x operand.Op) { + if inst, err := x86.VUCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +// Construct and append a VUCOMISS instruction to the active function. +// Operates on the global context. +func VUCOMISS(mx, x operand.Op) { ctx.VUCOMISS(mx, x) } + +// 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 +// Construct and append a VUNPCKHPD instruction to the active function. +func (c *Context) VUNPCKHPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKHPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VUNPCKHPD instruction to the active function. +// Operates on the global context. +func VUNPCKHPD(mxy, xy, xy1 operand.Op) { ctx.VUNPCKHPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VUNPCKHPS instruction to the active function. +func (c *Context) VUNPCKHPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKHPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VUNPCKHPS instruction to the active function. +// Operates on the global context. +func VUNPCKHPS(mxy, xy, xy1 operand.Op) { ctx.VUNPCKHPS(mxy, xy, xy1) } + +// 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 +// Construct and append a VUNPCKLPD instruction to the active function. +func (c *Context) VUNPCKLPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKLPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VUNPCKLPD instruction to the active function. +// Operates on the global context. +func VUNPCKLPD(mxy, xy, xy1 operand.Op) { ctx.VUNPCKLPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VUNPCKLPS instruction to the active function. +func (c *Context) VUNPCKLPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKLPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VUNPCKLPS instruction to the active function. +// Operates on the global context. +func VUNPCKLPS(mxy, xy, xy1 operand.Op) { ctx.VUNPCKLPS(mxy, xy, xy1) } + +// 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 +// Construct and append a VXORPD instruction to the active function. +func (c *Context) VXORPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VXORPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VXORPD instruction to the active function. +// Operates on the global context. +func VXORPD(mxy, xy, xy1 operand.Op) { ctx.VXORPD(mxy, xy, xy1) } + +// 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 +// Construct and append a VXORPS instruction to the active function. +func (c *Context) VXORPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VXORPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a VXORPS instruction to the active function. +// Operates on the global context. +func VXORPS(mxy, xy, xy1 operand.Op) { ctx.VXORPS(mxy, xy, xy1) } + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +// Construct and append a VZEROALL instruction to the active function. +func (c *Context) VZEROALL() { + if inst, err := x86.VZEROALL(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +// Construct and append a VZEROALL instruction to the active function. +// Operates on the global context. +func VZEROALL() { ctx.VZEROALL() } + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +// Construct and append a VZEROUPPER instruction to the active function. +func (c *Context) VZEROUPPER() { + if inst, err := x86.VZEROUPPER(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +// Construct and append a VZEROUPPER instruction to the active function. +// Operates on the global context. +func VZEROUPPER() { ctx.VZEROUPPER() } + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +// Construct and append a XADDB instruction to the active function. +func (c *Context) XADDB(r, mr operand.Op) { + if inst, err := x86.XADDB(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +// Construct and append a XADDB instruction to the active function. +// Operates on the global context. +func XADDB(r, mr operand.Op) { ctx.XADDB(r, mr) } + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +// Construct and append a XADDL instruction to the active function. +func (c *Context) XADDL(r, mr operand.Op) { + if inst, err := x86.XADDL(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +// Construct and append a XADDL instruction to the active function. +// Operates on the global context. +func XADDL(r, mr operand.Op) { ctx.XADDL(r, mr) } + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +// Construct and append a XADDQ instruction to the active function. +func (c *Context) XADDQ(r, mr operand.Op) { + if inst, err := x86.XADDQ(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +// Construct and append a XADDQ instruction to the active function. +// Operates on the global context. +func XADDQ(r, mr operand.Op) { ctx.XADDQ(r, mr) } + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +// Construct and append a XADDW instruction to the active function. +func (c *Context) XADDW(r, mr operand.Op) { + if inst, err := x86.XADDW(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +// Construct and append a XADDW instruction to the active function. +// Operates on the global context. +func XADDW(r, mr operand.Op) { ctx.XADDW(r, mr) } + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +// Construct and append a XCHGB instruction to the active function. +func (c *Context) XCHGB(mr, mr1 operand.Op) { + if inst, err := x86.XCHGB(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +// Construct and append a XCHGB instruction to the active function. +// Operates on the global context. +func XCHGB(mr, mr1 operand.Op) { ctx.XCHGB(mr, mr1) } + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +// Construct and append a XCHGL instruction to the active function. +func (c *Context) XCHGL(emr, emr1 operand.Op) { + if inst, err := x86.XCHGL(emr, emr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +// Construct and append a XCHGL instruction to the active function. +// Operates on the global context. +func XCHGL(emr, emr1 operand.Op) { ctx.XCHGL(emr, emr1) } + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +// Construct and append a XCHGQ instruction to the active function. +func (c *Context) XCHGQ(mr, mr1 operand.Op) { + if inst, err := x86.XCHGQ(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +// Construct and append a XCHGQ instruction to the active function. +// Operates on the global context. +func XCHGQ(mr, mr1 operand.Op) { ctx.XCHGQ(mr, mr1) } + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +// Construct and append a XCHGW instruction to the active function. +func (c *Context) XCHGW(amr, amr1 operand.Op) { + if inst, err := x86.XCHGW(amr, amr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +// Construct and append a XCHGW instruction to the active function. +// Operates on the global context. +func XCHGW(amr, amr1 operand.Op) { ctx.XCHGW(amr, amr1) } + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +// Construct and append a XGETBV instruction to the active function. +func (c *Context) XGETBV() { + if inst, err := x86.XGETBV(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +// Construct and append a XGETBV instruction to the active function. +// Operates on the global context. +func XGETBV() { ctx.XGETBV() } + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +// Construct and append a XLAT instruction to the active function. +func (c *Context) XLAT() { + if inst, err := x86.XLAT(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +// Construct and append a XLAT instruction to the active function. +// Operates on the global context. +func XLAT() { ctx.XLAT() } + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +// Construct and append a XORB instruction to the active function. +func (c *Context) XORB(imr, amr operand.Op) { + if inst, err := x86.XORB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +// Construct and append a XORB instruction to the active function. +// Operates on the global context. +func XORB(imr, amr operand.Op) { ctx.XORB(imr, amr) } + +// 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 +// Construct and append a XORL instruction to the active function. +func (c *Context) XORL(imr, emr operand.Op) { + if inst, err := x86.XORL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a XORL instruction to the active function. +// Operates on the global context. +func XORL(imr, emr operand.Op) { ctx.XORL(imr, emr) } + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +// Construct and append a XORPD instruction to the active function. +func (c *Context) XORPD(mx, x operand.Op) { + if inst, err := x86.XORPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +// Construct and append a XORPD instruction to the active function. +// Operates on the global context. +func XORPD(mx, x operand.Op) { ctx.XORPD(mx, x) } + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +// Construct and append a XORPS instruction to the active function. +func (c *Context) XORPS(mx, x operand.Op) { + if inst, err := x86.XORPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +// Construct and append a XORPS instruction to the active function. +// Operates on the global context. +func XORPS(mx, x operand.Op) { ctx.XORPS(mx, x) } + +// 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 +// Construct and append a XORQ instruction to the active function. +func (c *Context) XORQ(imr, mr operand.Op) { + if inst, err := x86.XORQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a XORQ instruction to the active function. +// Operates on the global context. +func XORQ(imr, mr operand.Op) { ctx.XORQ(imr, mr) } + +// 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 +// Construct and append a XORW instruction to the active function. +func (c *Context) XORW(imr, amr operand.Op) { + if inst, err := x86.XORW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// 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 +// Construct and append a XORW instruction to the active function. +// Operates on the global context. +func XORW(imr, amr operand.Op) { ctx.XORW(imr, amr) } diff --git a/vendor/github.com/mmcloughlin/avo/build/zmov.go b/vendor/github.com/mmcloughlin/avo/build/zmov.go new file mode 100644 index 0000000..ca9bb55 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/zmov.go @@ -0,0 +1,72 @@ +// Code generated by command: avogen -output zmov.go mov. DO NOT EDIT. + +package build + +import ( + "go/types" + + "github.com/mmcloughlin/avo/operand" +) + +func (c *Context) mov(a, b operand.Op, an, bn int, t *types.Basic) { + switch { + case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 1: + c.MOVB(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 4: + c.MOVBLSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 4: + c.MOVBLZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 8: + c.MOVBQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 8: + c.MOVBQZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 2: + c.MOVBWSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 2: + c.MOVBWZX(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 4: + c.MOVL(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 4 && bn == 8: + c.MOVLQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 4 && bn == 8: + c.MOVLQZX(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16: + c.MOVOU(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 8 && bn == 16: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 8: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 4 && bn == 16: + c.MOVSS(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 4: + c.MOVSS(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16: + c.MOVSS(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 2: + c.MOVW(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 4: + c.MOVWLSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 4: + c.MOVWLZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 8: + c.MOVWQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 8: + c.MOVWQZX(a, b) + default: + c.adderrormessage("could not deduce mov instruction") + } +} 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("", 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") +} diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE new file mode 100644 index 0000000..6a66aea --- /dev/null +++ b/vendor/golang.org/x/mod/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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 Google Inc. 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 +OWNER 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/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/mod/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go new file mode 100644 index 0000000..2988e3c --- /dev/null +++ b/vendor/golang.org/x/mod/semver/semver.go @@ -0,0 +1,388 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package semver implements comparison of semantic version strings. +// In this package, semantic version strings must begin with a leading "v", +// as in "v1.0.0". +// +// The general form of a semantic version string accepted by this package is +// +// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] +// +// where square brackets indicate optional parts of the syntax; +// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; +// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers +// using only alphanumeric characters and hyphens; and +// all-numeric PRERELEASE identifiers must not have leading zeros. +// +// This package follows Semantic Versioning 2.0.0 (see semver.org) +// with two exceptions. First, it requires the "v" prefix. Second, it recognizes +// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) +// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. +package semver + +// parsed returns the parsed form of a semantic version string. +type parsed struct { + major string + minor string + patch string + short string + prerelease string + build string + err string +} + +// IsValid reports whether v is a valid semantic version string. +func IsValid(v string) bool { + _, ok := parse(v) + return ok +} + +// Canonical returns the canonical formatting of the semantic version v. +// It fills in any missing .MINOR or .PATCH and discards build metadata. +// Two semantic versions compare equal only if their canonical formattings +// are identical strings. +// The canonical invalid semantic version is the empty string. +func Canonical(v string) string { + p, ok := parse(v) + if !ok { + return "" + } + if p.build != "" { + return v[:len(v)-len(p.build)] + } + if p.short != "" { + return v + p.short + } + return v +} + +// Major returns the major version prefix of the semantic version v. +// For example, Major("v2.1.0") == "v2". +// If v is an invalid semantic version string, Major returns the empty string. +func Major(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return v[:1+len(pv.major)] +} + +// MajorMinor returns the major.minor version prefix of the semantic version v. +// For example, MajorMinor("v2.1.0") == "v2.1". +// If v is an invalid semantic version string, MajorMinor returns the empty string. +func MajorMinor(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + i := 1 + len(pv.major) + if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { + return v[:j] + } + return v[:i] + "." + pv.minor +} + +// Prerelease returns the prerelease suffix of the semantic version v. +// For example, Prerelease("v2.1.0-pre+meta") == "-pre". +// If v is an invalid semantic version string, Prerelease returns the empty string. +func Prerelease(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.prerelease +} + +// Build returns the build suffix of the semantic version v. +// For example, Build("v2.1.0+meta") == "+meta". +// If v is an invalid semantic version string, Build returns the empty string. +func Build(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.build +} + +// Compare returns an integer comparing two versions according to +// semantic version precedence. +// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. +// +// An invalid semantic version string is considered less than a valid one. +// All invalid semantic version strings compare equal to each other. +func Compare(v, w string) int { + pv, ok1 := parse(v) + pw, ok2 := parse(w) + if !ok1 && !ok2 { + return 0 + } + if !ok1 { + return -1 + } + if !ok2 { + return +1 + } + if c := compareInt(pv.major, pw.major); c != 0 { + return c + } + if c := compareInt(pv.minor, pw.minor); c != 0 { + return c + } + if c := compareInt(pv.patch, pw.patch); c != 0 { + return c + } + return comparePrerelease(pv.prerelease, pw.prerelease) +} + +// Max canonicalizes its arguments and then returns the version string +// that compares greater. +func Max(v, w string) string { + v = Canonical(v) + w = Canonical(w) + if Compare(v, w) > 0 { + return v + } + return w +} + +func parse(v string) (p parsed, ok bool) { + if v == "" || v[0] != 'v' { + p.err = "missing v prefix" + return + } + p.major, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad major version" + return + } + if v == "" { + p.minor = "0" + p.patch = "0" + p.short = ".0.0" + return + } + if v[0] != '.' { + p.err = "bad minor prefix" + ok = false + return + } + p.minor, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad minor version" + return + } + if v == "" { + p.patch = "0" + p.short = ".0" + return + } + if v[0] != '.' { + p.err = "bad patch prefix" + ok = false + return + } + p.patch, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad patch version" + return + } + if len(v) > 0 && v[0] == '-' { + p.prerelease, v, ok = parsePrerelease(v) + if !ok { + p.err = "bad prerelease" + return + } + } + if len(v) > 0 && v[0] == '+' { + p.build, v, ok = parseBuild(v) + if !ok { + p.err = "bad build" + return + } + } + if v != "" { + p.err = "junk on end" + ok = false + return + } + ok = true + return +} + +func parseInt(v string) (t, rest string, ok bool) { + if v == "" { + return + } + if v[0] < '0' || '9' < v[0] { + return + } + i := 1 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + if v[0] == '0' && i != 1 { + return + } + return v[:i], v[i:], true +} + +func parsePrerelease(v string) (t, rest string, ok bool) { + // "A pre-release version MAY be denoted by appending a hyphen and + // a series of dot separated identifiers immediately following the patch version. + // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." + if v == "" || v[0] != '-' { + return + } + i := 1 + start := 1 + for i < len(v) && v[i] != '+' { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i || isBadNum(v[start:i]) { + return + } + start = i + 1 + } + i++ + } + if start == i || isBadNum(v[start:i]) { + return + } + return v[:i], v[i:], true +} + +func parseBuild(v string) (t, rest string, ok bool) { + if v == "" || v[0] != '+' { + return + } + i := 1 + start := 1 + for i < len(v) { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i { + return + } + start = i + 1 + } + i++ + } + if start == i { + return + } + return v[:i], v[i:], true +} + +func isIdentChar(c byte) bool { + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' +} + +func isBadNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) && i > 1 && v[0] == '0' +} + +func isNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) +} + +func compareInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} + +func comparePrerelease(x, y string) int { + // "When major, minor, and patch are equal, a pre-release version has + // lower precedence than a normal version. + // Example: 1.0.0-alpha < 1.0.0. + // Precedence for two pre-release versions with the same major, minor, + // and patch version MUST be determined by comparing each dot separated + // identifier from left to right until a difference is found as follows: + // identifiers consisting of only digits are compared numerically and + // identifiers with letters or hyphens are compared lexically in ASCII + // sort order. Numeric identifiers always have lower precedence than + // non-numeric identifiers. A larger set of pre-release fields has a + // higher precedence than a smaller set, if all of the preceding + // identifiers are equal. + // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < + // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." + if x == y { + return 0 + } + if x == "" { + return +1 + } + if y == "" { + return -1 + } + for x != "" && y != "" { + x = x[1:] // skip - or . + y = y[1:] // skip - or . + var dx, dy string + dx, x = nextIdent(x) + dy, y = nextIdent(y) + if dx != dy { + ix := isNum(dx) + iy := isNum(dy) + if ix != iy { + if ix { + return -1 + } else { + return +1 + } + } + if ix { + if len(dx) < len(dy) { + return -1 + } + if len(dx) > len(dy) { + return +1 + } + } + if dx < dy { + return -1 + } else { + return +1 + } + } + } + if x == "" { + return -1 + } else { + return +1 + } +} + +func nextIdent(x string) (dx, rest string) { + i := 0 + for i < len(x) && x[i] != '.' { + i++ + } + return x[:i], x[i:] +} diff --git a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go b/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go new file mode 100644 index 0000000..e07899b --- /dev/null +++ b/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go @@ -0,0 +1,30 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package unsafeheader contains header declarations for the Go runtime's +// slice and string implementations. +// +// This package allows x/sys to use types equivalent to +// reflect.SliceHeader and reflect.StringHeader without introducing +// a dependency on the (relatively heavy) "reflect" package. +package unsafeheader + +import ( + "unsafe" +) + +// Slice is the runtime representation of a slice. +// It cannot be used safely or portably and its representation may change in a later release. +type Slice struct { + Data unsafe.Pointer + Len int + Cap int +} + +// String is the runtime representation of a string. +// It cannot be used safely or portably and its representation may change in a later release. +type String struct { + Data unsafe.Pointer + Len int +} diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS new file mode 100644 index 0000000..15167cd --- /dev/null +++ b/vendor/golang.org/x/tools/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS new file mode 100644 index 0000000..1c4577e --- /dev/null +++ b/vendor/golang.org/x/tools/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE new file mode 100644 index 0000000..6a66aea --- /dev/null +++ b/vendor/golang.org/x/tools/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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 Google Inc. 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 +OWNER 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/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/tools/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go new file mode 100644 index 0000000..f8363d8 --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -0,0 +1,109 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gcexportdata provides functions for locating, reading, and +// writing export data files containing type information produced by the +// gc compiler. This package supports go1.7 export data format and all +// later versions. +// +// Although it might seem convenient for this package to live alongside +// go/types in the standard library, this would cause version skew +// problems for developer tools that use it, since they must be able to +// consume the outputs of the gc compiler both before and after a Go +// update such as from Go 1.7 to Go 1.8. Because this package lives in +// golang.org/x/tools, sites can update their version of this repo some +// time before the Go 1.8 release and rebuild and redeploy their +// developer tools, which will then be able to consume both Go 1.7 and +// Go 1.8 export data files, so they will work before and after the +// Go update. (See discussion at https://golang.org/issue/15651.) +// +package gcexportdata // import "golang.org/x/tools/go/gcexportdata" + +import ( + "bufio" + "bytes" + "fmt" + "go/token" + "go/types" + "io" + "io/ioutil" + + "golang.org/x/tools/go/internal/gcimporter" +) + +// Find returns the name of an object (.o) or archive (.a) file +// containing type information for the specified import path, +// using the workspace layout conventions of go/build. +// If no file was found, an empty filename is returned. +// +// A relative srcDir is interpreted relative to the current working directory. +// +// Find also returns the package's resolved (canonical) import path, +// reflecting the effects of srcDir and vendoring on importPath. +func Find(importPath, srcDir string) (filename, path string) { + return gcimporter.FindPkg(importPath, srcDir) +} + +// NewReader returns a reader for the export data section of an object +// (.o) or archive (.a) file read from r. The new reader may provide +// additional trailing data beyond the end of the export data. +func NewReader(r io.Reader) (io.Reader, error) { + buf := bufio.NewReader(r) + _, err := gcimporter.FindExportData(buf) + // If we ever switch to a zip-like archive format with the ToC + // at the end, we can return the correct portion of export data, + // but for now we must return the entire rest of the file. + return buf, err +} + +// Read reads export data from in, decodes it, and returns type +// information for the package. +// The package name is specified by path. +// File position information is added to fset. +// +// Read may inspect and add to the imports map to ensure that references +// within the export data to other packages are consistent. The caller +// must ensure that imports[path] does not exist, or exists but is +// incomplete (see types.Package.Complete), and Read inserts the +// resulting package into this map entry. +// +// On return, the state of the reader is undefined. +func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { + data, err := ioutil.ReadAll(in) + if err != nil { + return nil, fmt.Errorf("reading export data for %q: %v", path, err) + } + + if bytes.HasPrefix(data, []byte("!")) { + return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) + } + + // The App Engine Go runtime v1.6 uses the old export data format. + // TODO(adonovan): delete once v1.7 has been around for a while. + if bytes.HasPrefix(data, []byte("package ")) { + return gcimporter.ImportData(imports, path, path, bytes.NewReader(data)) + } + + // The indexed export format starts with an 'i'; the older + // binary export format starts with a 'c', 'd', or 'v' + // (from "version"). Select appropriate importer. + if len(data) > 0 && data[0] == 'i' { + _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) + return pkg, err + } + + _, pkg, err := gcimporter.BImportData(fset, imports, data, path) + return pkg, err +} + +// Write writes encoded type information for the specified package to out. +// The FileSet provides file position information for named objects. +func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + b, err := gcimporter.IExportData(fset, pkg) + if err != nil { + return err + } + _, err = out.Write(b) + return err +} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go new file mode 100644 index 0000000..efe221e --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -0,0 +1,73 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gcexportdata + +import ( + "fmt" + "go/token" + "go/types" + "os" +) + +// NewImporter returns a new instance of the types.Importer interface +// that reads type information from export data files written by gc. +// The Importer also satisfies types.ImporterFrom. +// +// Export data files are located using "go build" workspace conventions +// and the build.Default context. +// +// Use this importer instead of go/importer.For("gc", ...) to avoid the +// version-skew problems described in the documentation of this package, +// or to control the FileSet or access the imports map populated during +// package loading. +// +func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { + return importer{fset, imports} +} + +type importer struct { + fset *token.FileSet + imports map[string]*types.Package +} + +func (imp importer) Import(importPath string) (*types.Package, error) { + return imp.ImportFrom(importPath, "", 0) +} + +func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { + filename, path := Find(importPath, srcDir) + if filename == "" { + if importPath == "unsafe" { + // Even for unsafe, call Find first in case + // the package was vendored. + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %s", importPath) + } + + if pkg, ok := imp.imports[path]; ok && pkg.Complete() { + return pkg, nil // cache hit + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + f.Close() + if err != nil { + // add file name to error + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + r, err := NewReader(f) + if err != nil { + return nil, err + } + + return Read(r, imp.fset, imp.imports, path) +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go new file mode 100644 index 0000000..a807d0a --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go @@ -0,0 +1,852 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Binary package export. +// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go; +// see that file for specification of the format. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/ast" + "go/constant" + "go/token" + "go/types" + "math" + "math/big" + "sort" + "strings" +) + +// If debugFormat is set, each integer and string value is preceded by a marker +// and position information in the encoding. This mechanism permits an importer +// to recognize immediately when it is out of sync. The importer recognizes this +// mode automatically (i.e., it can import export data produced with debugging +// support even if debugFormat is not set at the time of import). This mode will +// lead to massively larger export data (by a factor of 2 to 3) and should only +// be enabled during development and debugging. +// +// NOTE: This flag is the first flag to enable if importing dies because of +// (suspected) format errors, and whenever a change is made to the format. +const debugFormat = false // default: false + +// If trace is set, debugging output is printed to std out. +const trace = false // default: false + +// Current export format version. Increase with each format change. +// Note: The latest binary (non-indexed) export format is at version 6. +// This exporter is still at level 4, but it doesn't matter since +// the binary importer can handle older versions just fine. +// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE +// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE +// 4: type name objects support type aliases, uses aliasTag +// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used) +// 2: removed unused bool in ODCL export (compiler only) +// 1: header format change (more regular), export package for _ struct fields +// 0: Go1.7 encoding +const exportVersion = 4 + +// trackAllTypes enables cycle tracking for all types, not just named +// types. The existing compiler invariants assume that unnamed types +// that are not completely set up are not used, or else there are spurious +// errors. +// If disabled, only named types are tracked, possibly leading to slightly +// less efficient encoding in rare cases. It also prevents the export of +// some corner-case type declarations (but those are not handled correctly +// with with the textual export format either). +// TODO(gri) enable and remove once issues caused by it are fixed +const trackAllTypes = false + +type exporter struct { + fset *token.FileSet + out bytes.Buffer + + // object -> index maps, indexed in order of serialization + strIndex map[string]int + pkgIndex map[*types.Package]int + typIndex map[types.Type]int + + // position encoding + posInfoFormat bool + prevFile string + prevLine int + + // debugging support + written int // bytes written + indent int // for trace +} + +// internalError represents an error generated inside this package. +type internalError string + +func (e internalError) Error() string { return "gcimporter: " + string(e) } + +func internalErrorf(format string, args ...interface{}) error { + return internalError(fmt.Sprintf(format, args...)) +} + +// BExportData returns binary export data for pkg. +// If no file set is provided, position info will be missing. +func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) { + defer func() { + if e := recover(); e != nil { + if ierr, ok := e.(internalError); ok { + err = ierr + return + } + // Not an internal error; panic again. + panic(e) + } + }() + + p := exporter{ + fset: fset, + strIndex: map[string]int{"": 0}, // empty string is mapped to 0 + pkgIndex: make(map[*types.Package]int), + typIndex: make(map[types.Type]int), + posInfoFormat: true, // TODO(gri) might become a flag, eventually + } + + // write version info + // The version string must start with "version %d" where %d is the version + // number. Additional debugging information may follow after a blank; that + // text is ignored by the importer. + p.rawStringln(fmt.Sprintf("version %d", exportVersion)) + var debug string + if debugFormat { + debug = "debug" + } + p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly + p.bool(trackAllTypes) + p.bool(p.posInfoFormat) + + // --- generic export data --- + + // populate type map with predeclared "known" types + for index, typ := range predeclared() { + p.typIndex[typ] = index + } + if len(p.typIndex) != len(predeclared()) { + return nil, internalError("duplicate entries in type map?") + } + + // write package data + p.pkg(pkg, true) + if trace { + p.tracef("\n") + } + + // write objects + objcount := 0 + scope := pkg.Scope() + for _, name := range scope.Names() { + if !ast.IsExported(name) { + continue + } + if trace { + p.tracef("\n") + } + p.obj(scope.Lookup(name)) + objcount++ + } + + // indicate end of list + if trace { + p.tracef("\n") + } + p.tag(endTag) + + // for self-verification only (redundant) + p.int(objcount) + + if trace { + p.tracef("\n") + } + + // --- end of export data --- + + return p.out.Bytes(), nil +} + +func (p *exporter) pkg(pkg *types.Package, emptypath bool) { + if pkg == nil { + panic(internalError("unexpected nil pkg")) + } + + // if we saw the package before, write its index (>= 0) + if i, ok := p.pkgIndex[pkg]; ok { + p.index('P', i) + return + } + + // otherwise, remember the package, write the package tag (< 0) and package data + if trace { + p.tracef("P%d = { ", len(p.pkgIndex)) + defer p.tracef("} ") + } + p.pkgIndex[pkg] = len(p.pkgIndex) + + p.tag(packageTag) + p.string(pkg.Name()) + if emptypath { + p.string("") + } else { + p.string(pkg.Path()) + } +} + +func (p *exporter) obj(obj types.Object) { + switch obj := obj.(type) { + case *types.Const: + p.tag(constTag) + p.pos(obj) + p.qualifiedName(obj) + p.typ(obj.Type()) + p.value(obj.Val()) + + case *types.TypeName: + if obj.IsAlias() { + p.tag(aliasTag) + p.pos(obj) + p.qualifiedName(obj) + } else { + p.tag(typeTag) + } + p.typ(obj.Type()) + + case *types.Var: + p.tag(varTag) + p.pos(obj) + p.qualifiedName(obj) + p.typ(obj.Type()) + + case *types.Func: + p.tag(funcTag) + p.pos(obj) + p.qualifiedName(obj) + sig := obj.Type().(*types.Signature) + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) + + default: + panic(internalErrorf("unexpected object %v (%T)", obj, obj)) + } +} + +func (p *exporter) pos(obj types.Object) { + if !p.posInfoFormat { + return + } + + file, line := p.fileLine(obj) + if file == p.prevFile { + // common case: write line delta + // delta == 0 means different file or no line change + delta := line - p.prevLine + p.int(delta) + if delta == 0 { + p.int(-1) // -1 means no file change + } + } else { + // different file + p.int(0) + // Encode filename as length of common prefix with previous + // filename, followed by (possibly empty) suffix. Filenames + // frequently share path prefixes, so this can save a lot + // of space and make export data size less dependent on file + // path length. The suffix is unlikely to be empty because + // file names tend to end in ".go". + n := commonPrefixLen(p.prevFile, file) + p.int(n) // n >= 0 + p.string(file[n:]) // write suffix only + p.prevFile = file + p.int(line) + } + p.prevLine = line +} + +func (p *exporter) fileLine(obj types.Object) (file string, line int) { + if p.fset != nil { + pos := p.fset.Position(obj.Pos()) + file = pos.Filename + line = pos.Line + } + return +} + +func commonPrefixLen(a, b string) int { + if len(a) > len(b) { + a, b = b, a + } + // len(a) <= len(b) + i := 0 + for i < len(a) && a[i] == b[i] { + i++ + } + return i +} + +func (p *exporter) qualifiedName(obj types.Object) { + p.string(obj.Name()) + p.pkg(obj.Pkg(), false) +} + +func (p *exporter) typ(t types.Type) { + if t == nil { + panic(internalError("nil type")) + } + + // Possible optimization: Anonymous pointer types *T where + // T is a named type are common. We could canonicalize all + // such types *T to a single type PT = *T. This would lead + // to at most one *T entry in typIndex, and all future *T's + // would be encoded as the respective index directly. Would + // save 1 byte (pointerTag) per *T and reduce the typIndex + // size (at the cost of a canonicalization map). We can do + // this later, without encoding format change. + + // if we saw the type before, write its index (>= 0) + if i, ok := p.typIndex[t]; ok { + p.index('T', i) + return + } + + // otherwise, remember the type, write the type tag (< 0) and type data + if trackAllTypes { + if trace { + p.tracef("T%d = {>\n", len(p.typIndex)) + defer p.tracef("<\n} ") + } + p.typIndex[t] = len(p.typIndex) + } + + switch t := t.(type) { + case *types.Named: + if !trackAllTypes { + // if we don't track all types, track named types now + p.typIndex[t] = len(p.typIndex) + } + + p.tag(namedTag) + p.pos(t.Obj()) + p.qualifiedName(t.Obj()) + p.typ(t.Underlying()) + if !types.IsInterface(t) { + p.assocMethods(t) + } + + case *types.Array: + p.tag(arrayTag) + p.int64(t.Len()) + p.typ(t.Elem()) + + case *types.Slice: + p.tag(sliceTag) + p.typ(t.Elem()) + + case *dddSlice: + p.tag(dddTag) + p.typ(t.elem) + + case *types.Struct: + p.tag(structTag) + p.fieldList(t) + + case *types.Pointer: + p.tag(pointerTag) + p.typ(t.Elem()) + + case *types.Signature: + p.tag(signatureTag) + p.paramList(t.Params(), t.Variadic()) + p.paramList(t.Results(), false) + + case *types.Interface: + p.tag(interfaceTag) + p.iface(t) + + case *types.Map: + p.tag(mapTag) + p.typ(t.Key()) + p.typ(t.Elem()) + + case *types.Chan: + p.tag(chanTag) + p.int(int(3 - t.Dir())) // hack + p.typ(t.Elem()) + + default: + panic(internalErrorf("unexpected type %T: %s", t, t)) + } +} + +func (p *exporter) assocMethods(named *types.Named) { + // Sort methods (for determinism). + var methods []*types.Func + for i := 0; i < named.NumMethods(); i++ { + methods = append(methods, named.Method(i)) + } + sort.Sort(methodsByName(methods)) + + p.int(len(methods)) + + if trace && methods != nil { + p.tracef("associated methods {>\n") + } + + for i, m := range methods { + if trace && i > 0 { + p.tracef("\n") + } + + p.pos(m) + name := m.Name() + p.string(name) + if !exported(name) { + p.pkg(m.Pkg(), false) + } + + sig := m.Type().(*types.Signature) + p.paramList(types.NewTuple(sig.Recv()), false) + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) + p.int(0) // dummy value for go:nointerface pragma - ignored by importer + } + + if trace && methods != nil { + p.tracef("<\n} ") + } +} + +type methodsByName []*types.Func + +func (x methodsByName) Len() int { return len(x) } +func (x methodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() } + +func (p *exporter) fieldList(t *types.Struct) { + if trace && t.NumFields() > 0 { + p.tracef("fields {>\n") + defer p.tracef("<\n} ") + } + + p.int(t.NumFields()) + for i := 0; i < t.NumFields(); i++ { + if trace && i > 0 { + p.tracef("\n") + } + p.field(t.Field(i)) + p.string(t.Tag(i)) + } +} + +func (p *exporter) field(f *types.Var) { + if !f.IsField() { + panic(internalError("field expected")) + } + + p.pos(f) + p.fieldName(f) + p.typ(f.Type()) +} + +func (p *exporter) iface(t *types.Interface) { + // TODO(gri): enable importer to load embedded interfaces, + // then emit Embeddeds and ExplicitMethods separately here. + p.int(0) + + n := t.NumMethods() + if trace && n > 0 { + p.tracef("methods {>\n") + defer p.tracef("<\n} ") + } + p.int(n) + for i := 0; i < n; i++ { + if trace && i > 0 { + p.tracef("\n") + } + p.method(t.Method(i)) + } +} + +func (p *exporter) method(m *types.Func) { + sig := m.Type().(*types.Signature) + if sig.Recv() == nil { + panic(internalError("method expected")) + } + + p.pos(m) + p.string(m.Name()) + if m.Name() != "_" && !ast.IsExported(m.Name()) { + p.pkg(m.Pkg(), false) + } + + // interface method; no need to encode receiver. + p.paramList(sig.Params(), sig.Variadic()) + p.paramList(sig.Results(), false) +} + +func (p *exporter) fieldName(f *types.Var) { + name := f.Name() + + if f.Anonymous() { + // anonymous field - we distinguish between 3 cases: + // 1) field name matches base type name and is exported + // 2) field name matches base type name and is not exported + // 3) field name doesn't match base type name (alias name) + bname := basetypeName(f.Type()) + if name == bname { + if ast.IsExported(name) { + name = "" // 1) we don't need to know the field name or package + } else { + name = "?" // 2) use unexported name "?" to force package export + } + } else { + // 3) indicate alias and export name as is + // (this requires an extra "@" but this is a rare case) + p.string("@") + } + } + + p.string(name) + if name != "" && !ast.IsExported(name) { + p.pkg(f.Pkg(), false) + } +} + +func basetypeName(typ types.Type) string { + switch typ := deref(typ).(type) { + case *types.Basic: + return typ.Name() + case *types.Named: + return typ.Obj().Name() + default: + return "" // unnamed type + } +} + +func (p *exporter) paramList(params *types.Tuple, variadic bool) { + // use negative length to indicate unnamed parameters + // (look at the first parameter only since either all + // names are present or all are absent) + n := params.Len() + if n > 0 && params.At(0).Name() == "" { + n = -n + } + p.int(n) + for i := 0; i < params.Len(); i++ { + q := params.At(i) + t := q.Type() + if variadic && i == params.Len()-1 { + t = &dddSlice{t.(*types.Slice).Elem()} + } + p.typ(t) + if n > 0 { + name := q.Name() + p.string(name) + if name != "_" { + p.pkg(q.Pkg(), false) + } + } + p.string("") // no compiler-specific info + } +} + +func (p *exporter) value(x constant.Value) { + if trace { + p.tracef("= ") + } + + switch x.Kind() { + case constant.Bool: + tag := falseTag + if constant.BoolVal(x) { + tag = trueTag + } + p.tag(tag) + + case constant.Int: + if v, exact := constant.Int64Val(x); exact { + // common case: x fits into an int64 - use compact encoding + p.tag(int64Tag) + p.int64(v) + return + } + // uncommon case: large x - use float encoding + // (powers of 2 will be encoded efficiently with exponent) + p.tag(floatTag) + p.float(constant.ToFloat(x)) + + case constant.Float: + p.tag(floatTag) + p.float(x) + + case constant.Complex: + p.tag(complexTag) + p.float(constant.Real(x)) + p.float(constant.Imag(x)) + + case constant.String: + p.tag(stringTag) + p.string(constant.StringVal(x)) + + case constant.Unknown: + // package contains type errors + p.tag(unknownTag) + + default: + panic(internalErrorf("unexpected value %v (%T)", x, x)) + } +} + +func (p *exporter) float(x constant.Value) { + if x.Kind() != constant.Float { + panic(internalErrorf("unexpected constant %v, want float", x)) + } + // extract sign (there is no -0) + sign := constant.Sign(x) + if sign == 0 { + // x == 0 + p.int(0) + return + } + // x != 0 + + var f big.Float + if v, exact := constant.Float64Val(x); exact { + // float64 + f.SetFloat64(v) + } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { + // TODO(gri): add big.Rat accessor to constant.Value. + r := valueToRat(num) + f.SetRat(r.Quo(r, valueToRat(denom))) + } else { + // Value too large to represent as a fraction => inaccessible. + // TODO(gri): add big.Float accessor to constant.Value. + f.SetFloat64(math.MaxFloat64) // FIXME + } + + // extract exponent such that 0.5 <= m < 1.0 + var m big.Float + exp := f.MantExp(&m) + + // extract mantissa as *big.Int + // - set exponent large enough so mant satisfies mant.IsInt() + // - get *big.Int from mant + m.SetMantExp(&m, int(m.MinPrec())) + mant, acc := m.Int(nil) + if acc != big.Exact { + panic(internalError("internal error")) + } + + p.int(sign) + p.int(exp) + p.string(string(mant.Bytes())) +} + +func valueToRat(x constant.Value) *big.Rat { + // Convert little-endian to big-endian. + // I can't believe this is necessary. + bytes := constant.Bytes(x) + for i := 0; i < len(bytes)/2; i++ { + bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] + } + return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) +} + +func (p *exporter) bool(b bool) bool { + if trace { + p.tracef("[") + defer p.tracef("= %v] ", b) + } + + x := 0 + if b { + x = 1 + } + p.int(x) + return b +} + +// ---------------------------------------------------------------------------- +// Low-level encoders + +func (p *exporter) index(marker byte, index int) { + if index < 0 { + panic(internalError("invalid index < 0")) + } + if debugFormat { + p.marker('t') + } + if trace { + p.tracef("%c%d ", marker, index) + } + p.rawInt64(int64(index)) +} + +func (p *exporter) tag(tag int) { + if tag >= 0 { + panic(internalError("invalid tag >= 0")) + } + if debugFormat { + p.marker('t') + } + if trace { + p.tracef("%s ", tagString[-tag]) + } + p.rawInt64(int64(tag)) +} + +func (p *exporter) int(x int) { + p.int64(int64(x)) +} + +func (p *exporter) int64(x int64) { + if debugFormat { + p.marker('i') + } + if trace { + p.tracef("%d ", x) + } + p.rawInt64(x) +} + +func (p *exporter) string(s string) { + if debugFormat { + p.marker('s') + } + if trace { + p.tracef("%q ", s) + } + // if we saw the string before, write its index (>= 0) + // (the empty string is mapped to 0) + if i, ok := p.strIndex[s]; ok { + p.rawInt64(int64(i)) + return + } + // otherwise, remember string and write its negative length and bytes + p.strIndex[s] = len(p.strIndex) + p.rawInt64(-int64(len(s))) + for i := 0; i < len(s); i++ { + p.rawByte(s[i]) + } +} + +// marker emits a marker byte and position information which makes +// it easy for a reader to detect if it is "out of sync". Used for +// debugFormat format only. +func (p *exporter) marker(m byte) { + p.rawByte(m) + // Enable this for help tracking down the location + // of an incorrect marker when running in debugFormat. + if false && trace { + p.tracef("#%d ", p.written) + } + p.rawInt64(int64(p.written)) +} + +// rawInt64 should only be used by low-level encoders. +func (p *exporter) rawInt64(x int64) { + var tmp [binary.MaxVarintLen64]byte + n := binary.PutVarint(tmp[:], x) + for i := 0; i < n; i++ { + p.rawByte(tmp[i]) + } +} + +// rawStringln should only be used to emit the initial version string. +func (p *exporter) rawStringln(s string) { + for i := 0; i < len(s); i++ { + p.rawByte(s[i]) + } + p.rawByte('\n') +} + +// rawByte is the bottleneck interface to write to p.out. +// rawByte escapes b as follows (any encoding does that +// hides '$'): +// +// '$' => '|' 'S' +// '|' => '|' '|' +// +// Necessary so other tools can find the end of the +// export data by searching for "$$". +// rawByte should only be used by low-level encoders. +func (p *exporter) rawByte(b byte) { + switch b { + case '$': + // write '$' as '|' 'S' + b = 'S' + fallthrough + case '|': + // write '|' as '|' '|' + p.out.WriteByte('|') + p.written++ + } + p.out.WriteByte(b) + p.written++ +} + +// tracef is like fmt.Printf but it rewrites the format string +// to take care of indentation. +func (p *exporter) tracef(format string, args ...interface{}) { + if strings.ContainsAny(format, "<>\n") { + var buf bytes.Buffer + for i := 0; i < len(format); i++ { + // no need to deal with runes + ch := format[i] + switch ch { + case '>': + p.indent++ + continue + case '<': + p.indent-- + continue + } + buf.WriteByte(ch) + if ch == '\n' { + for j := p.indent; j > 0; j-- { + buf.WriteString(". ") + } + } + } + format = buf.String() + } + fmt.Printf(format, args...) +} + +// Debugging support. +// (tagString is only used when tracing is enabled) +var tagString = [...]string{ + // Packages + -packageTag: "package", + + // Types + -namedTag: "named type", + -arrayTag: "array", + -sliceTag: "slice", + -dddTag: "ddd", + -structTag: "struct", + -pointerTag: "pointer", + -signatureTag: "signature", + -interfaceTag: "interface", + -mapTag: "map", + -chanTag: "chan", + + // Values + -falseTag: "false", + -trueTag: "true", + -int64Tag: "int64", + -floatTag: "float", + -fractionTag: "fraction", + -complexTag: "complex", + -stringTag: "string", + -unknownTag: "unknown", + + // Type aliases + -aliasTag: "alias", +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go new file mode 100644 index 0000000..e9f73d1 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go @@ -0,0 +1,1039 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go. + +package gcimporter + +import ( + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +type importer struct { + imports map[string]*types.Package + data []byte + importpath string + buf []byte // for reading strings + version int // export format version + + // object lists + strList []string // in order of appearance + pathList []string // in order of appearance + pkgList []*types.Package // in order of appearance + typList []types.Type // in order of appearance + interfaceList []*types.Interface // for delayed completion only + trackAllTypes bool + + // position encoding + posInfoFormat bool + prevFile string + prevLine int + fake fakeFileSet + + // debugging support + debugFormat bool + read int // bytes read +} + +// BImportData imports a package from the serialized package data +// and returns the number of bytes consumed and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + // catch panics and return them as errors + const currentVersion = 6 + version := -1 // unknown version + defer func() { + if e := recover(); e != nil { + // Return a (possibly nil or incomplete) package unchanged (see #16088). + if version > currentVersion { + err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) + } else { + err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) + } + } + }() + + p := importer{ + imports: imports, + data: data, + importpath: path, + version: version, + strList: []string{""}, // empty string is mapped to 0 + pathList: []string{""}, // empty string is mapped to 0 + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*token.File), + }, + } + + // read version info + var versionstr string + if b := p.rawByte(); b == 'c' || b == 'd' { + // Go1.7 encoding; first byte encodes low-level + // encoding format (compact vs debug). + // For backward-compatibility only (avoid problems with + // old installed packages). Newly compiled packages use + // the extensible format string. + // TODO(gri) Remove this support eventually; after Go1.8. + if b == 'd' { + p.debugFormat = true + } + p.trackAllTypes = p.rawByte() == 'a' + p.posInfoFormat = p.int() != 0 + versionstr = p.string() + if versionstr == "v1" { + version = 0 + } + } else { + // Go1.8 extensible encoding + // read version string and extract version number (ignore anything after the version number) + versionstr = p.rawStringln(b) + if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" { + if v, err := strconv.Atoi(s[1]); err == nil && v > 0 { + version = v + } + } + } + p.version = version + + // read version specific flags - extend as necessary + switch p.version { + // case currentVersion: + // ... + // fallthrough + case currentVersion, 5, 4, 3, 2, 1: + p.debugFormat = p.rawStringln(p.rawByte()) == "debug" + p.trackAllTypes = p.int() != 0 + p.posInfoFormat = p.int() != 0 + case 0: + // Go1.7 encoding format - nothing to do here + default: + errorf("unknown bexport format version %d (%q)", p.version, versionstr) + } + + // --- generic export data --- + + // populate typList with predeclared "known" types + p.typList = append(p.typList, predeclared()...) + + // read package data + pkg = p.pkg() + + // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go) + objcount := 0 + for { + tag := p.tagOrIndex() + if tag == endTag { + break + } + p.obj(tag) + objcount++ + } + + // self-verification + if count := p.int(); count != objcount { + errorf("got %d objects; want %d", objcount, count) + } + + // ignore compiler-specific import data + + // complete interfaces + // TODO(gri) re-investigate if we still need to do this in a delayed fashion + for _, typ := range p.interfaceList { + typ.Complete() + } + + // record all referenced packages as imports + list := append(([]*types.Package)(nil), p.pkgList[1:]...) + sort.Sort(byPath(list)) + pkg.SetImports(list) + + // package was imported completely and without errors + pkg.MarkComplete() + + return p.read, pkg, nil +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Sprintf(format, args...)) +} + +func (p *importer) pkg() *types.Package { + // if the package was seen before, i is its index (>= 0) + i := p.tagOrIndex() + if i >= 0 { + return p.pkgList[i] + } + + // otherwise, i is the package tag (< 0) + if i != packageTag { + errorf("unexpected package tag %d version %d", i, p.version) + } + + // read package data + name := p.string() + var path string + if p.version >= 5 { + path = p.path() + } else { + path = p.string() + } + if p.version >= 6 { + p.int() // package height; unused by go/types + } + + // we should never see an empty package name + if name == "" { + errorf("empty package name in import") + } + + // an empty path denotes the package we are currently importing; + // it must be the first package we see + if (path == "") != (len(p.pkgList) == 0) { + errorf("package path %q for pkg index %d", path, len(p.pkgList)) + } + + // if the package was imported before, use that one; otherwise create a new one + if path == "" { + path = p.importpath + } + pkg := p.imports[path] + if pkg == nil { + pkg = types.NewPackage(path, name) + p.imports[path] = pkg + } else if pkg.Name() != name { + errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path) + } + p.pkgList = append(p.pkgList, pkg) + + return pkg +} + +// objTag returns the tag value for each object kind. +func objTag(obj types.Object) int { + switch obj.(type) { + case *types.Const: + return constTag + case *types.TypeName: + return typeTag + case *types.Var: + return varTag + case *types.Func: + return funcTag + default: + errorf("unexpected object: %v (%T)", obj, obj) // panics + panic("unreachable") + } +} + +func sameObj(a, b types.Object) bool { + // Because unnamed types are not canonicalized, we cannot simply compare types for + // (pointer) identity. + // Ideally we'd check equality of constant values as well, but this is good enough. + return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type()) +} + +func (p *importer) declare(obj types.Object) { + pkg := obj.Pkg() + if alt := pkg.Scope().Insert(obj); alt != nil { + // This can only trigger if we import a (non-type) object a second time. + // Excluding type aliases, this cannot happen because 1) we only import a package + // once; and b) we ignore compiler-specific export data which may contain + // functions whose inlined function bodies refer to other functions that + // were already imported. + // However, type aliases require reexporting the original type, so we need + // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go, + // method importer.obj, switch case importing functions). + // TODO(gri) review/update this comment once the gc compiler handles type aliases. + if !sameObj(obj, alt) { + errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt) + } + } +} + +func (p *importer) obj(tag int) { + switch tag { + case constTag: + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + val := p.value() + p.declare(types.NewConst(pos, pkg, name, typ, val)) + + case aliasTag: + // TODO(gri) verify type alias hookup is correct + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + p.declare(types.NewTypeName(pos, pkg, name, typ)) + + case typeTag: + p.typ(nil, nil) + + case varTag: + pos := p.pos() + pkg, name := p.qualifiedName() + typ := p.typ(nil, nil) + p.declare(types.NewVar(pos, pkg, name, typ)) + + case funcTag: + pos := p.pos() + pkg, name := p.qualifiedName() + params, isddd := p.paramList() + result, _ := p.paramList() + sig := types.NewSignature(nil, params, result, isddd) + p.declare(types.NewFunc(pos, pkg, name, sig)) + + default: + errorf("unexpected object tag %d", tag) + } +} + +const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go + +func (p *importer) pos() token.Pos { + if !p.posInfoFormat { + return token.NoPos + } + + file := p.prevFile + line := p.prevLine + delta := p.int() + line += delta + if p.version >= 5 { + if delta == deltaNewFile { + if n := p.int(); n >= 0 { + // file changed + file = p.path() + line = n + } + } + } else { + if delta == 0 { + if n := p.int(); n >= 0 { + // file changed + file = p.prevFile[:n] + p.string() + line = p.int() + } + } + } + p.prevFile = file + p.prevLine = line + + return p.fake.pos(file, line, 0) +} + +// Synthesize a token.Pos +type fakeFileSet struct { + fset *token.FileSet + files map[string]*token.File +} + +func (s *fakeFileSet) pos(file string, line, column int) token.Pos { + // TODO(mdempsky): Make use of column. + + // Since we don't know the set of needed file positions, we + // reserve maxlines positions per file. + const maxlines = 64 * 1024 + f := s.files[file] + if f == nil { + f = s.fset.AddFile(file, -1, maxlines) + s.files[file] = f + // Allocate the fake linebreak indices on first use. + // TODO(adonovan): opt: save ~512KB using a more complex scheme? + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + f.SetLines(fakeLines) + } + + if line > maxlines { + line = 1 + } + + // Treat the file as if it contained only newlines + // and column=1: use the line number as the offset. + return f.Pos(line - 1) +} + +var ( + fakeLines []int + fakeLinesOnce sync.Once +) + +func (p *importer) qualifiedName() (pkg *types.Package, name string) { + name = p.string() + pkg = p.pkg() + return +} + +func (p *importer) record(t types.Type) { + p.typList = append(p.typList, t) +} + +// A dddSlice is a types.Type representing ...T parameters. +// It only appears for parameter types and does not escape +// the importer. +type dddSlice struct { + elem types.Type +} + +func (t *dddSlice) Underlying() types.Type { return t } +func (t *dddSlice) String() string { return "..." + t.elem.String() } + +// parent is the package which declared the type; parent == nil means +// the package currently imported. The parent package is needed for +// exported struct fields and interface methods which don't contain +// explicit package information in the export data. +// +// A non-nil tname is used as the "owner" of the result type; i.e., +// the result type is the underlying type of tname. tname is used +// to give interface methods a named receiver type where possible. +func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type { + // if the type was seen before, i is its index (>= 0) + i := p.tagOrIndex() + if i >= 0 { + return p.typList[i] + } + + // otherwise, i is the type tag (< 0) + switch i { + case namedTag: + // read type object + pos := p.pos() + parent, name := p.qualifiedName() + scope := parent.Scope() + obj := scope.Lookup(name) + + // if the object doesn't exist yet, create and insert it + if obj == nil { + obj = types.NewTypeName(pos, parent, name, nil) + scope.Insert(obj) + } + + if _, ok := obj.(*types.TypeName); !ok { + errorf("pkg = %s, name = %s => %s", parent, name, obj) + } + + // associate new named type with obj if it doesn't exist yet + t0 := types.NewNamed(obj.(*types.TypeName), nil, nil) + + // but record the existing type, if any + tname := obj.Type().(*types.Named) // tname is either t0 or the existing type + p.record(tname) + + // read underlying type + t0.SetUnderlying(p.typ(parent, t0)) + + // interfaces don't have associated methods + if types.IsInterface(t0) { + return tname + } + + // read associated methods + for i := p.int(); i > 0; i-- { + // TODO(gri) replace this with something closer to fieldName + pos := p.pos() + name := p.string() + if !exported(name) { + p.pkg() + } + + recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? + params, isddd := p.paramList() + result, _ := p.paramList() + p.int() // go:nointerface pragma - discarded + + sig := types.NewSignature(recv.At(0), params, result, isddd) + t0.AddMethod(types.NewFunc(pos, parent, name, sig)) + } + + return tname + + case arrayTag: + t := new(types.Array) + if p.trackAllTypes { + p.record(t) + } + + n := p.int64() + *t = *types.NewArray(p.typ(parent, nil), n) + return t + + case sliceTag: + t := new(types.Slice) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewSlice(p.typ(parent, nil)) + return t + + case dddTag: + t := new(dddSlice) + if p.trackAllTypes { + p.record(t) + } + + t.elem = p.typ(parent, nil) + return t + + case structTag: + t := new(types.Struct) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewStruct(p.fieldList(parent)) + return t + + case pointerTag: + t := new(types.Pointer) + if p.trackAllTypes { + p.record(t) + } + + *t = *types.NewPointer(p.typ(parent, nil)) + return t + + case signatureTag: + t := new(types.Signature) + if p.trackAllTypes { + p.record(t) + } + + params, isddd := p.paramList() + result, _ := p.paramList() + *t = *types.NewSignature(nil, params, result, isddd) + return t + + case interfaceTag: + // Create a dummy entry in the type list. This is safe because we + // cannot expect the interface type to appear in a cycle, as any + // such cycle must contain a named type which would have been + // first defined earlier. + // TODO(gri) Is this still true now that we have type aliases? + // See issue #23225. + n := len(p.typList) + if p.trackAllTypes { + p.record(nil) + } + + var embeddeds []types.Type + for n := p.int(); n > 0; n-- { + p.pos() + embeddeds = append(embeddeds, p.typ(parent, nil)) + } + + t := newInterface(p.methodList(parent, tname), embeddeds) + p.interfaceList = append(p.interfaceList, t) + if p.trackAllTypes { + p.typList[n] = t + } + return t + + case mapTag: + t := new(types.Map) + if p.trackAllTypes { + p.record(t) + } + + key := p.typ(parent, nil) + val := p.typ(parent, nil) + *t = *types.NewMap(key, val) + return t + + case chanTag: + t := new(types.Chan) + if p.trackAllTypes { + p.record(t) + } + + dir := chanDir(p.int()) + val := p.typ(parent, nil) + *t = *types.NewChan(dir, val) + return t + + default: + errorf("unexpected type tag %d", i) // panics + panic("unreachable") + } +} + +func chanDir(d int) types.ChanDir { + // tag values must match the constants in cmd/compile/internal/gc/go.go + switch d { + case 1 /* Crecv */ : + return types.RecvOnly + case 2 /* Csend */ : + return types.SendOnly + case 3 /* Cboth */ : + return types.SendRecv + default: + errorf("unexpected channel dir %d", d) + return 0 + } +} + +func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) { + if n := p.int(); n > 0 { + fields = make([]*types.Var, n) + tags = make([]string, n) + for i := range fields { + fields[i], tags[i] = p.field(parent) + } + } + return +} + +func (p *importer) field(parent *types.Package) (*types.Var, string) { + pos := p.pos() + pkg, name, alias := p.fieldName(parent) + typ := p.typ(parent, nil) + tag := p.string() + + anonymous := false + if name == "" { + // anonymous field - typ must be T or *T and T must be a type name + switch typ := deref(typ).(type) { + case *types.Basic: // basic types are named types + pkg = nil // // objects defined in Universe scope have no package + name = typ.Name() + case *types.Named: + name = typ.Obj().Name() + default: + errorf("named base type expected") + } + anonymous = true + } else if alias { + // anonymous field: we have an explicit name because it's an alias + anonymous = true + } + + return types.NewField(pos, pkg, name, typ, anonymous), tag +} + +func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) { + if n := p.int(); n > 0 { + methods = make([]*types.Func, n) + for i := range methods { + methods[i] = p.method(parent, baseType) + } + } + return +} + +func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func { + pos := p.pos() + pkg, name, _ := p.fieldName(parent) + // If we don't have a baseType, use a nil receiver. + // A receiver using the actual interface type (which + // we don't know yet) will be filled in when we call + // types.Interface.Complete. + var recv *types.Var + if baseType != nil { + recv = types.NewVar(token.NoPos, parent, "", baseType) + } + params, isddd := p.paramList() + result, _ := p.paramList() + sig := types.NewSignature(recv, params, result, isddd) + return types.NewFunc(pos, pkg, name, sig) +} + +func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) { + name = p.string() + pkg = parent + if pkg == nil { + // use the imported package instead + pkg = p.pkgList[0] + } + if p.version == 0 && name == "_" { + // version 0 didn't export a package for _ fields + return + } + switch name { + case "": + // 1) field name matches base type name and is exported: nothing to do + case "?": + // 2) field name matches base type name and is not exported: need package + name = "" + pkg = p.pkg() + case "@": + // 3) field name doesn't match type name (alias) + name = p.string() + alias = true + fallthrough + default: + if !exported(name) { + pkg = p.pkg() + } + } + return +} + +func (p *importer) paramList() (*types.Tuple, bool) { + n := p.int() + if n == 0 { + return nil, false + } + // negative length indicates unnamed parameters + named := true + if n < 0 { + n = -n + named = false + } + // n > 0 + params := make([]*types.Var, n) + isddd := false + for i := range params { + params[i], isddd = p.param(named) + } + return types.NewTuple(params...), isddd +} + +func (p *importer) param(named bool) (*types.Var, bool) { + t := p.typ(nil, nil) + td, isddd := t.(*dddSlice) + if isddd { + t = types.NewSlice(td.elem) + } + + var pkg *types.Package + var name string + if named { + name = p.string() + if name == "" { + errorf("expected named parameter") + } + if name != "_" { + pkg = p.pkg() + } + if i := strings.Index(name, "·"); i > 0 { + name = name[:i] // cut off gc-specific parameter numbering + } + } + + // read and discard compiler-specific info + p.string() + + return types.NewVar(token.NoPos, pkg, name, t), isddd +} + +func exported(name string) bool { + ch, _ := utf8.DecodeRuneInString(name) + return unicode.IsUpper(ch) +} + +func (p *importer) value() constant.Value { + switch tag := p.tagOrIndex(); tag { + case falseTag: + return constant.MakeBool(false) + case trueTag: + return constant.MakeBool(true) + case int64Tag: + return constant.MakeInt64(p.int64()) + case floatTag: + return p.float() + case complexTag: + re := p.float() + im := p.float() + return constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + case stringTag: + return constant.MakeString(p.string()) + case unknownTag: + return constant.MakeUnknown() + default: + errorf("unexpected value tag %d", tag) // panics + panic("unreachable") + } +} + +func (p *importer) float() constant.Value { + sign := p.int() + if sign == 0 { + return constant.MakeInt64(0) + } + + exp := p.int() + mant := []byte(p.string()) // big endian + + // remove leading 0's if any + for len(mant) > 0 && mant[0] == 0 { + mant = mant[1:] + } + + // convert to little endian + // TODO(gri) go/constant should have a more direct conversion function + // (e.g., once it supports a big.Float based implementation) + for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 { + mant[i], mant[j] = mant[j], mant[i] + } + + // adjust exponent (constant.MakeFromBytes creates an integer value, + // but mant represents the mantissa bits such that 0.5 <= mant < 1.0) + exp -= len(mant) << 3 + if len(mant) > 0 { + for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 { + exp++ + } + } + + x := constant.MakeFromBytes(mant) + switch { + case exp < 0: + d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) + x = constant.BinaryOp(x, token.QUO, d) + case exp > 0: + x = constant.Shift(x, token.SHL, uint(exp)) + } + + if sign < 0 { + x = constant.UnaryOp(token.SUB, x, 0) + } + return x +} + +// ---------------------------------------------------------------------------- +// Low-level decoders + +func (p *importer) tagOrIndex() int { + if p.debugFormat { + p.marker('t') + } + + return int(p.rawInt64()) +} + +func (p *importer) int() int { + x := p.int64() + if int64(int(x)) != x { + errorf("exported integer too large") + } + return int(x) +} + +func (p *importer) int64() int64 { + if p.debugFormat { + p.marker('i') + } + + return p.rawInt64() +} + +func (p *importer) path() string { + if p.debugFormat { + p.marker('p') + } + // if the path was seen before, i is its index (>= 0) + // (the empty string is at index 0) + i := p.rawInt64() + if i >= 0 { + return p.pathList[i] + } + // otherwise, i is the negative path length (< 0) + a := make([]string, -i) + for n := range a { + a[n] = p.string() + } + s := strings.Join(a, "/") + p.pathList = append(p.pathList, s) + return s +} + +func (p *importer) string() string { + if p.debugFormat { + p.marker('s') + } + // if the string was seen before, i is its index (>= 0) + // (the empty string is at index 0) + i := p.rawInt64() + if i >= 0 { + return p.strList[i] + } + // otherwise, i is the negative string length (< 0) + if n := int(-i); n <= cap(p.buf) { + p.buf = p.buf[:n] + } else { + p.buf = make([]byte, n) + } + for i := range p.buf { + p.buf[i] = p.rawByte() + } + s := string(p.buf) + p.strList = append(p.strList, s) + return s +} + +func (p *importer) marker(want byte) { + if got := p.rawByte(); got != want { + errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read) + } + + pos := p.read + if n := int(p.rawInt64()); n != pos { + errorf("incorrect position: got %d; want %d", n, pos) + } +} + +// rawInt64 should only be used by low-level decoders. +func (p *importer) rawInt64() int64 { + i, err := binary.ReadVarint(p) + if err != nil { + errorf("read error: %v", err) + } + return i +} + +// rawStringln should only be used to read the initial version string. +func (p *importer) rawStringln(b byte) string { + p.buf = p.buf[:0] + for b != '\n' { + p.buf = append(p.buf, b) + b = p.rawByte() + } + return string(p.buf) +} + +// needed for binary.ReadVarint in rawInt64 +func (p *importer) ReadByte() (byte, error) { + return p.rawByte(), nil +} + +// byte is the bottleneck interface for reading p.data. +// It unescapes '|' 'S' to '$' and '|' '|' to '|'. +// rawByte should only be used by low-level decoders. +func (p *importer) rawByte() byte { + b := p.data[0] + r := 1 + if b == '|' { + b = p.data[1] + r = 2 + switch b { + case 'S': + b = '$' + case '|': + // nothing to do + default: + errorf("unexpected escape sequence in export data") + } + } + p.data = p.data[r:] + p.read += r + return b + +} + +// ---------------------------------------------------------------------------- +// Export format + +// Tags. Must be < 0. +const ( + // Objects + packageTag = -(iota + 1) + constTag + typeTag + varTag + funcTag + endTag + + // Types + namedTag + arrayTag + sliceTag + dddTag + structTag + pointerTag + signatureTag + interfaceTag + mapTag + chanTag + + // Values + falseTag + trueTag + int64Tag + floatTag + fractionTag // not used by gc + complexTag + stringTag + nilTag // only used by gc (appears in exported inlined function bodies) + unknownTag // not used by gc (only appears in packages with errors) + + // Type aliases + aliasTag +) + +var predeclOnce sync.Once +var predecl []types.Type // initialized lazily + +func predeclared() []types.Type { + predeclOnce.Do(func() { + // initialize lazily to be sure that all + // elements have been initialized before + predecl = []types.Type{ // basic types + types.Typ[types.Bool], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.Typ[types.Uintptr], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Complex64], + types.Typ[types.Complex128], + types.Typ[types.String], + + // basic type aliases + types.Universe.Lookup("byte").Type(), + types.Universe.Lookup("rune").Type(), + + // error + types.Universe.Lookup("error").Type(), + + // untyped types + types.Typ[types.UntypedBool], + types.Typ[types.UntypedInt], + types.Typ[types.UntypedRune], + types.Typ[types.UntypedFloat], + types.Typ[types.UntypedComplex], + types.Typ[types.UntypedString], + types.Typ[types.UntypedNil], + + // package unsafe + types.Typ[types.UnsafePointer], + + // invalid type + types.Typ[types.Invalid], // only appears in packages with errors + + // used internally by gc; never used by this package or in .a files + anyType{}, + } + }) + return predecl +} + +type anyType struct{} + +func (t anyType) Underlying() types.Type { return t } +func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go new file mode 100644 index 0000000..f33dc56 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go @@ -0,0 +1,93 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. + +// This file implements FindExportData. + +package gcimporter + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" +) + +func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { + // See $GOROOT/include/ar.h. + hdr := make([]byte, 16+12+6+6+8+10+2) + _, err = io.ReadFull(r, hdr) + if err != nil { + return + } + // leave for debugging + if false { + fmt.Printf("header: %s", hdr) + } + s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) + size, err = strconv.Atoi(s) + if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { + err = fmt.Errorf("invalid archive header") + return + } + name = strings.TrimSpace(string(hdr[:16])) + return +} + +// FindExportData positions the reader r at the beginning of the +// export data section of an underlying GC-created object/archive +// file by reading from it. The reader must be positioned at the +// start of the file before calling this function. The hdr result +// is the string before the export data, either "$$" or "$$B". +// +func FindExportData(r *bufio.Reader) (hdr string, err error) { + // Read first line to make sure this is an object file. + line, err := r.ReadSlice('\n') + if err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + + if string(line) == "!\n" { + // Archive file. Scan to __.PKGDEF. + var name string + if name, _, err = readGopackHeader(r); err != nil { + return + } + + // First entry should be __.PKGDEF. + if name != "__.PKGDEF" { + err = fmt.Errorf("go archive is missing __.PKGDEF") + return + } + + // Read first line of __.PKGDEF data, so that line + // is once again the first line of the input. + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + } + + // Now at __.PKGDEF in archive or still at beginning of file. + // Either way, line should begin with "go object ". + if !strings.HasPrefix(string(line), "go object ") { + err = fmt.Errorf("not a Go object file") + return + } + + // Skip over object header to export data. + // Begins after first line starting with $$. + for line[0] != '$' { + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + } + hdr = string(line) + + return +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go new file mode 100644 index 0000000..8dcd8bb --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -0,0 +1,1078 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a modified copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go, +// but it also contains the original source-based importer code for Go1.6. +// Once we stop supporting 1.6, we can remove that code. + +// Package gcimporter provides various functions for reading +// gc-generated object files that can be used to implement the +// Importer interface defined by the Go 1.5 standard library package. +package gcimporter // import "golang.org/x/tools/go/internal/gcimporter" + +import ( + "bufio" + "errors" + "fmt" + "go/build" + "go/constant" + "go/token" + "go/types" + "io" + "io/ioutil" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "text/scanner" +) + +// debugging/development support +const debug = false + +var pkgExts = [...]string{".a", ".o"} + +// FindPkg returns the filename and unique package id for an import +// path based on package information provided by build.Import (using +// the build.Default build.Context). A relative srcDir is interpreted +// relative to the current working directory. +// If no file was found, an empty filename is returned. +// +func FindPkg(path, srcDir string) (filename, id string) { + if path == "" { + return + } + + var noext string + switch { + default: + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + // Don't require the source files to be present. + if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 + srcDir = abs + } + bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) + if bp.PkgObj == "" { + id = path // make sure we have an id to print in error message + return + } + noext = strings.TrimSuffix(bp.PkgObj, ".a") + id = bp.ImportPath + + case build.IsLocalImport(path): + // "./x" -> "/this/directory/x.ext", "/this/directory/x" + noext = filepath.Join(srcDir, path) + id = noext + + case filepath.IsAbs(path): + // for completeness only - go/build.Import + // does not support absolute imports + // "/x" -> "/x.ext", "/x" + noext = path + id = path + } + + if false { // for debugging + if path != id { + fmt.Printf("%s -> %s\n", path, id) + } + } + + // try extensions + for _, ext := range pkgExts { + filename = noext + ext + if f, err := os.Stat(filename); err == nil && !f.IsDir() { + return + } + } + + filename = "" // not found + return +} + +// ImportData imports a package by reading the gc-generated export data, +// adds the corresponding package object to the packages map indexed by id, +// and returns the object. +// +// The packages map must contains all packages already imported. The data +// reader position must be the beginning of the export data section. The +// filename is only used in error messages. +// +// If packages[id] contains the completely imported package, that package +// can be used directly, and there is no need to call this function (but +// there is also no harm but for extra time used). +// +func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) { + // support for parser error handling + defer func() { + switch r := recover().(type) { + case nil: + // nothing to do + case importError: + err = r + default: + panic(r) // internal error + } + }() + + var p parser + p.init(filename, id, data, packages) + pkg = p.parseExport() + + return +} + +// Import imports a gc-generated package given its import path and srcDir, adds +// the corresponding package object to the packages map, and returns the object. +// The packages map must contain all packages already imported. +// +func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { + var rc io.ReadCloser + var filename, id string + if lookup != nil { + // With custom lookup specified, assume that caller has + // converted path to a canonical import path for use in the map. + if path == "unsafe" { + return types.Unsafe, nil + } + id = path + + // No need to re-import if the package was imported completely before. + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + f, err := lookup(path) + if err != nil { + return nil, err + } + rc = f + } else { + filename, id = FindPkg(path, srcDir) + if filename == "" { + if path == "unsafe" { + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %q", id) + } + + // no need to re-import if the package was imported completely before + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + if err != nil { + // add file name to error + err = fmt.Errorf("%s: %v", filename, err) + } + }() + rc = f + } + defer rc.Close() + + var hdr string + buf := bufio.NewReader(rc) + if hdr, err = FindExportData(buf); err != nil { + return + } + + switch hdr { + case "$$\n": + // Work-around if we don't have a filename; happens only if lookup != nil. + // Either way, the filename is only needed for importer error messages, so + // this is fine. + if filename == "" { + filename = path + } + return ImportData(packages, filename, id, buf) + + case "$$B\n": + var data []byte + data, err = ioutil.ReadAll(buf) + if err != nil { + break + } + + // TODO(gri): allow clients of go/importer to provide a FileSet. + // Or, define a new standard go/types/gcexportdata package. + fset := token.NewFileSet() + + // The indexed export format starts with an 'i'; the older + // binary export format starts with a 'c', 'd', or 'v' + // (from "version"). Select appropriate importer. + if len(data) > 0 && data[0] == 'i' { + _, pkg, err = IImportData(fset, packages, data[1:], id) + } else { + _, pkg, err = BImportData(fset, packages, data, id) + } + + default: + err = fmt.Errorf("unknown export data header: %q", hdr) + } + + return +} + +// ---------------------------------------------------------------------------- +// Parser + +// TODO(gri) Imported objects don't have position information. +// Ideally use the debug table line info; alternatively +// create some fake position (or the position of the +// import). That way error messages referring to imported +// objects can print meaningful information. + +// parser parses the exports inside a gc compiler-produced +// object/archive file and populates its scope with the results. +type parser struct { + scanner scanner.Scanner + tok rune // current token + lit string // literal string; only valid for Ident, Int, String tokens + id string // package id of imported package + sharedPkgs map[string]*types.Package // package id -> package object (across importer) + localPkgs map[string]*types.Package // package id -> package object (just this package) +} + +func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) { + p.scanner.Init(src) + p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } + p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments + p.scanner.Whitespace = 1<<'\t' | 1<<' ' + p.scanner.Filename = filename // for good error messages + p.next() + p.id = id + p.sharedPkgs = packages + if debug { + // check consistency of packages map + for _, pkg := range packages { + if pkg.Name() == "" { + fmt.Printf("no package name for %s\n", pkg.Path()) + } + } + } +} + +func (p *parser) next() { + p.tok = p.scanner.Scan() + switch p.tok { + case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·': + p.lit = p.scanner.TokenText() + default: + p.lit = "" + } + if debug { + fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit) + } +} + +func declTypeName(pkg *types.Package, name string) *types.TypeName { + scope := pkg.Scope() + if obj := scope.Lookup(name); obj != nil { + return obj.(*types.TypeName) + } + obj := types.NewTypeName(token.NoPos, pkg, name, nil) + // a named type may be referred to before the underlying type + // is known - set it up + types.NewNamed(obj, nil, nil) + scope.Insert(obj) + return obj +} + +// ---------------------------------------------------------------------------- +// Error handling + +// Internal errors are boxed as importErrors. +type importError struct { + pos scanner.Position + err error +} + +func (e importError) Error() string { + return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) +} + +func (p *parser) error(err interface{}) { + if s, ok := err.(string); ok { + err = errors.New(s) + } + // panic with a runtime.Error if err is not an error + panic(importError{p.scanner.Pos(), err.(error)}) +} + +func (p *parser) errorf(format string, args ...interface{}) { + p.error(fmt.Sprintf(format, args...)) +} + +func (p *parser) expect(tok rune) string { + lit := p.lit + if p.tok != tok { + p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) + } + p.next() + return lit +} + +func (p *parser) expectSpecial(tok string) { + sep := 'x' // not white space + i := 0 + for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' { + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + i++ + } + if i < len(tok) { + p.errorf("expected %q, got %q", tok, tok[0:i]) + } +} + +func (p *parser) expectKeyword(keyword string) { + lit := p.expect(scanner.Ident) + if lit != keyword { + p.errorf("expected keyword %s, got %q", keyword, lit) + } +} + +// ---------------------------------------------------------------------------- +// Qualified and unqualified names + +// PackageId = string_lit . +// +func (p *parser) parsePackageID() string { + id, err := strconv.Unquote(p.expect(scanner.String)) + if err != nil { + p.error(err) + } + // id == "" stands for the imported package id + // (only known at time of package installation) + if id == "" { + id = p.id + } + return id +} + +// PackageName = ident . +// +func (p *parser) parsePackageName() string { + return p.expect(scanner.Ident) +} + +// dotIdentifier = ( ident | '·' ) { ident | int | '·' } . +func (p *parser) parseDotIdent() string { + ident := "" + if p.tok != scanner.Int { + sep := 'x' // not white space + for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' { + ident += p.lit + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + } + } + if ident == "" { + p.expect(scanner.Ident) // use expect() for error handling + } + return ident +} + +// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) . +// +func (p *parser) parseQualifiedName() (id, name string) { + p.expect('@') + id = p.parsePackageID() + p.expect('.') + // Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields. + if p.tok == '?' { + p.next() + } else { + name = p.parseDotIdent() + } + return +} + +// getPkg returns the package for a given id. If the package is +// not found, create the package and add it to the p.localPkgs +// and p.sharedPkgs maps. name is the (expected) name of the +// package. If name == "", the package name is expected to be +// set later via an import clause in the export data. +// +// id identifies a package, usually by a canonical package path like +// "encoding/json" but possibly by a non-canonical import path like +// "./json". +// +func (p *parser) getPkg(id, name string) *types.Package { + // package unsafe is not in the packages maps - handle explicitly + if id == "unsafe" { + return types.Unsafe + } + + pkg := p.localPkgs[id] + if pkg == nil { + // first import of id from this package + pkg = p.sharedPkgs[id] + if pkg == nil { + // first import of id by this importer; + // add (possibly unnamed) pkg to shared packages + pkg = types.NewPackage(id, name) + p.sharedPkgs[id] = pkg + } + // add (possibly unnamed) pkg to local packages + if p.localPkgs == nil { + p.localPkgs = make(map[string]*types.Package) + } + p.localPkgs[id] = pkg + } else if name != "" { + // package exists already and we have an expected package name; + // make sure names match or set package name if necessary + if pname := pkg.Name(); pname == "" { + pkg.SetName(name) + } else if pname != name { + p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name) + } + } + return pkg +} + +// parseExportedName is like parseQualifiedName, but +// the package id is resolved to an imported *types.Package. +// +func (p *parser) parseExportedName() (pkg *types.Package, name string) { + id, name := p.parseQualifiedName() + pkg = p.getPkg(id, "") + return +} + +// ---------------------------------------------------------------------------- +// Types + +// BasicType = identifier . +// +func (p *parser) parseBasicType() types.Type { + id := p.expect(scanner.Ident) + obj := types.Universe.Lookup(id) + if obj, ok := obj.(*types.TypeName); ok { + return obj.Type() + } + p.errorf("not a basic type: %s", id) + return nil +} + +// ArrayType = "[" int_lit "]" Type . +// +func (p *parser) parseArrayType(parent *types.Package) types.Type { + // "[" already consumed and lookahead known not to be "]" + lit := p.expect(scanner.Int) + p.expect(']') + elem := p.parseType(parent) + n, err := strconv.ParseInt(lit, 10, 64) + if err != nil { + p.error(err) + } + return types.NewArray(elem, n) +} + +// MapType = "map" "[" Type "]" Type . +// +func (p *parser) parseMapType(parent *types.Package) types.Type { + p.expectKeyword("map") + p.expect('[') + key := p.parseType(parent) + p.expect(']') + elem := p.parseType(parent) + return types.NewMap(key, elem) +} + +// Name = identifier | "?" | QualifiedName . +// +// For unqualified and anonymous names, the returned package is the parent +// package unless parent == nil, in which case the returned package is the +// package being imported. (The parent package is not nil if the the name +// is an unqualified struct field or interface method name belonging to a +// type declared in another package.) +// +// For qualified names, the returned package is nil (and not created if +// it doesn't exist yet) unless materializePkg is set (which creates an +// unnamed package with valid package path). In the latter case, a +// subsequent import clause is expected to provide a name for the package. +// +func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) { + pkg = parent + if pkg == nil { + pkg = p.sharedPkgs[p.id] + } + switch p.tok { + case scanner.Ident: + name = p.lit + p.next() + case '?': + // anonymous + p.next() + case '@': + // exported name prefixed with package path + pkg = nil + var id string + id, name = p.parseQualifiedName() + if materializePkg { + pkg = p.getPkg(id, "") + } + default: + p.error("name expected") + } + return +} + +func deref(typ types.Type) types.Type { + if p, _ := typ.(*types.Pointer); p != nil { + return p.Elem() + } + return typ +} + +// Field = Name Type [ string_lit ] . +// +func (p *parser) parseField(parent *types.Package) (*types.Var, string) { + pkg, name := p.parseName(parent, true) + + if name == "_" { + // Blank fields should be package-qualified because they + // are unexported identifiers, but gc does not qualify them. + // Assuming that the ident belongs to the current package + // causes types to change during re-exporting, leading + // to spurious "can't assign A to B" errors from go/types. + // As a workaround, pretend all blank fields belong + // to the same unique dummy package. + const blankpkg = "<_>" + pkg = p.getPkg(blankpkg, blankpkg) + } + + typ := p.parseType(parent) + anonymous := false + if name == "" { + // anonymous field - typ must be T or *T and T must be a type name + switch typ := deref(typ).(type) { + case *types.Basic: // basic types are named types + pkg = nil // objects defined in Universe scope have no package + name = typ.Name() + case *types.Named: + name = typ.Obj().Name() + default: + p.errorf("anonymous field expected") + } + anonymous = true + } + tag := "" + if p.tok == scanner.String { + s := p.expect(scanner.String) + var err error + tag, err = strconv.Unquote(s) + if err != nil { + p.errorf("invalid struct tag %s: %s", s, err) + } + } + return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag +} + +// StructType = "struct" "{" [ FieldList ] "}" . +// FieldList = Field { ";" Field } . +// +func (p *parser) parseStructType(parent *types.Package) types.Type { + var fields []*types.Var + var tags []string + + p.expectKeyword("struct") + p.expect('{') + for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { + if i > 0 { + p.expect(';') + } + fld, tag := p.parseField(parent) + if tag != "" && tags == nil { + tags = make([]string, i) + } + if tags != nil { + tags = append(tags, tag) + } + fields = append(fields, fld) + } + p.expect('}') + + return types.NewStruct(fields, tags) +} + +// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . +// +func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { + _, name := p.parseName(nil, false) + // remove gc-specific parameter numbering + if i := strings.Index(name, "·"); i >= 0 { + name = name[:i] + } + if p.tok == '.' { + p.expectSpecial("...") + isVariadic = true + } + typ := p.parseType(nil) + if isVariadic { + typ = types.NewSlice(typ) + } + // ignore argument tag (e.g. "noescape") + if p.tok == scanner.String { + p.next() + } + // TODO(gri) should we provide a package? + par = types.NewVar(token.NoPos, nil, name, typ) + return +} + +// Parameters = "(" [ ParameterList ] ")" . +// ParameterList = { Parameter "," } Parameter . +// +func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { + p.expect('(') + for p.tok != ')' && p.tok != scanner.EOF { + if len(list) > 0 { + p.expect(',') + } + par, variadic := p.parseParameter() + list = append(list, par) + if variadic { + if isVariadic { + p.error("... not on final argument") + } + isVariadic = true + } + } + p.expect(')') + + return +} + +// Signature = Parameters [ Result ] . +// Result = Type | Parameters . +// +func (p *parser) parseSignature(recv *types.Var) *types.Signature { + params, isVariadic := p.parseParameters() + + // optional result type + var results []*types.Var + if p.tok == '(' { + var variadic bool + results, variadic = p.parseParameters() + if variadic { + p.error("... not permitted on result type") + } + } + + return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic) +} + +// InterfaceType = "interface" "{" [ MethodList ] "}" . +// MethodList = Method { ";" Method } . +// Method = Name Signature . +// +// The methods of embedded interfaces are always "inlined" +// by the compiler and thus embedded interfaces are never +// visible in the export data. +// +func (p *parser) parseInterfaceType(parent *types.Package) types.Type { + var methods []*types.Func + + p.expectKeyword("interface") + p.expect('{') + for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ { + if i > 0 { + p.expect(';') + } + pkg, name := p.parseName(parent, true) + sig := p.parseSignature(nil) + methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig)) + } + p.expect('}') + + // Complete requires the type's embedded interfaces to be fully defined, + // but we do not define any + return newInterface(methods, nil).Complete() +} + +// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . +// +func (p *parser) parseChanType(parent *types.Package) types.Type { + dir := types.SendRecv + if p.tok == scanner.Ident { + p.expectKeyword("chan") + if p.tok == '<' { + p.expectSpecial("<-") + dir = types.SendOnly + } + } else { + p.expectSpecial("<-") + p.expectKeyword("chan") + dir = types.RecvOnly + } + elem := p.parseType(parent) + return types.NewChan(dir, elem) +} + +// Type = +// BasicType | TypeName | ArrayType | SliceType | StructType | +// PointerType | FuncType | InterfaceType | MapType | ChanType | +// "(" Type ")" . +// +// BasicType = ident . +// TypeName = ExportedName . +// SliceType = "[" "]" Type . +// PointerType = "*" Type . +// FuncType = "func" Signature . +// +func (p *parser) parseType(parent *types.Package) types.Type { + switch p.tok { + case scanner.Ident: + switch p.lit { + default: + return p.parseBasicType() + case "struct": + return p.parseStructType(parent) + case "func": + // FuncType + p.next() + return p.parseSignature(nil) + case "interface": + return p.parseInterfaceType(parent) + case "map": + return p.parseMapType(parent) + case "chan": + return p.parseChanType(parent) + } + case '@': + // TypeName + pkg, name := p.parseExportedName() + return declTypeName(pkg, name).Type() + case '[': + p.next() // look ahead + if p.tok == ']' { + // SliceType + p.next() + return types.NewSlice(p.parseType(parent)) + } + return p.parseArrayType(parent) + case '*': + // PointerType + p.next() + return types.NewPointer(p.parseType(parent)) + case '<': + return p.parseChanType(parent) + case '(': + // "(" Type ")" + p.next() + typ := p.parseType(parent) + p.expect(')') + return typ + } + p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit) + return nil +} + +// ---------------------------------------------------------------------------- +// Declarations + +// ImportDecl = "import" PackageName PackageId . +// +func (p *parser) parseImportDecl() { + p.expectKeyword("import") + name := p.parsePackageName() + p.getPkg(p.parsePackageID(), name) +} + +// int_lit = [ "+" | "-" ] { "0" ... "9" } . +// +func (p *parser) parseInt() string { + s := "" + switch p.tok { + case '-': + s = "-" + p.next() + case '+': + p.next() + } + return s + p.expect(scanner.Int) +} + +// number = int_lit [ "p" int_lit ] . +// +func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) { + // mantissa + mant := constant.MakeFromLiteral(p.parseInt(), token.INT, 0) + if mant == nil { + panic("invalid mantissa") + } + + if p.lit == "p" { + // exponent (base 2) + p.next() + exp, err := strconv.ParseInt(p.parseInt(), 10, 0) + if err != nil { + p.error(err) + } + if exp < 0 { + denom := constant.MakeInt64(1) + denom = constant.Shift(denom, token.SHL, uint(-exp)) + typ = types.Typ[types.UntypedFloat] + val = constant.BinaryOp(mant, token.QUO, denom) + return + } + if exp > 0 { + mant = constant.Shift(mant, token.SHL, uint(exp)) + } + typ = types.Typ[types.UntypedFloat] + val = mant + return + } + + typ = types.Typ[types.UntypedInt] + val = mant + return +} + +// ConstDecl = "const" ExportedName [ Type ] "=" Literal . +// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . +// bool_lit = "true" | "false" . +// complex_lit = "(" float_lit "+" float_lit "i" ")" . +// rune_lit = "(" int_lit "+" int_lit ")" . +// string_lit = `"` { unicode_char } `"` . +// +func (p *parser) parseConstDecl() { + p.expectKeyword("const") + pkg, name := p.parseExportedName() + + var typ0 types.Type + if p.tok != '=' { + // constant types are never structured - no need for parent type + typ0 = p.parseType(nil) + } + + p.expect('=') + var typ types.Type + var val constant.Value + switch p.tok { + case scanner.Ident: + // bool_lit + if p.lit != "true" && p.lit != "false" { + p.error("expected true or false") + } + typ = types.Typ[types.UntypedBool] + val = constant.MakeBool(p.lit == "true") + p.next() + + case '-', scanner.Int: + // int_lit + typ, val = p.parseNumber() + + case '(': + // complex_lit or rune_lit + p.next() + if p.tok == scanner.Char { + p.next() + p.expect('+') + typ = types.Typ[types.UntypedRune] + _, val = p.parseNumber() + p.expect(')') + break + } + _, re := p.parseNumber() + p.expect('+') + _, im := p.parseNumber() + p.expectKeyword("i") + p.expect(')') + typ = types.Typ[types.UntypedComplex] + val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + + case scanner.Char: + // rune_lit + typ = types.Typ[types.UntypedRune] + val = constant.MakeFromLiteral(p.lit, token.CHAR, 0) + p.next() + + case scanner.String: + // string_lit + typ = types.Typ[types.UntypedString] + val = constant.MakeFromLiteral(p.lit, token.STRING, 0) + p.next() + + default: + p.errorf("expected literal got %s", scanner.TokenString(p.tok)) + } + + if typ0 == nil { + typ0 = typ + } + + pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) +} + +// TypeDecl = "type" ExportedName Type . +// +func (p *parser) parseTypeDecl() { + p.expectKeyword("type") + pkg, name := p.parseExportedName() + obj := declTypeName(pkg, name) + + // The type object may have been imported before and thus already + // have a type associated with it. We still need to parse the type + // structure, but throw it away if the object already has a type. + // This ensures that all imports refer to the same type object for + // a given type declaration. + typ := p.parseType(pkg) + + if name := obj.Type().(*types.Named); name.Underlying() == nil { + name.SetUnderlying(typ) + } +} + +// VarDecl = "var" ExportedName Type . +// +func (p *parser) parseVarDecl() { + p.expectKeyword("var") + pkg, name := p.parseExportedName() + typ := p.parseType(pkg) + pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ)) +} + +// Func = Signature [ Body ] . +// Body = "{" ... "}" . +// +func (p *parser) parseFunc(recv *types.Var) *types.Signature { + sig := p.parseSignature(recv) + if p.tok == '{' { + p.next() + for i := 1; i > 0; p.next() { + switch p.tok { + case '{': + i++ + case '}': + i-- + } + } + } + return sig +} + +// MethodDecl = "func" Receiver Name Func . +// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . +// +func (p *parser) parseMethodDecl() { + // "func" already consumed + p.expect('(') + recv, _ := p.parseParameter() // receiver + p.expect(')') + + // determine receiver base type object + base := deref(recv.Type()).(*types.Named) + + // parse method name, signature, and possibly inlined body + _, name := p.parseName(nil, false) + sig := p.parseFunc(recv) + + // methods always belong to the same package as the base type object + pkg := base.Obj().Pkg() + + // add method to type unless type was imported before + // and method exists already + // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small. + base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) +} + +// FuncDecl = "func" ExportedName Func . +// +func (p *parser) parseFuncDecl() { + // "func" already consumed + pkg, name := p.parseExportedName() + typ := p.parseFunc(nil) + pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ)) +} + +// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . +// +func (p *parser) parseDecl() { + if p.tok == scanner.Ident { + switch p.lit { + case "import": + p.parseImportDecl() + case "const": + p.parseConstDecl() + case "type": + p.parseTypeDecl() + case "var": + p.parseVarDecl() + case "func": + p.next() // look ahead + if p.tok == '(' { + p.parseMethodDecl() + } else { + p.parseFuncDecl() + } + } + } + p.expect('\n') +} + +// ---------------------------------------------------------------------------- +// Export + +// Export = "PackageClause { Decl } "$$" . +// PackageClause = "package" PackageName [ "safe" ] "\n" . +// +func (p *parser) parseExport() *types.Package { + p.expectKeyword("package") + name := p.parsePackageName() + if p.tok == scanner.Ident && p.lit == "safe" { + // package was compiled with -u option - ignore + p.next() + } + p.expect('\n') + + pkg := p.getPkg(p.id, name) + + for p.tok != '$' && p.tok != scanner.EOF { + p.parseDecl() + } + + if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { + // don't call next()/expect() since reading past the + // export data may cause scanner errors (e.g. NUL chars) + p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) + } + + if n := p.scanner.ErrorCount; n != 0 { + p.errorf("expected no scanner errors, got %d", n) + } + + // Record all locally referenced packages as imports. + var imports []*types.Package + for id, pkg2 := range p.localPkgs { + if pkg2.Name() == "" { + p.errorf("%s package has no name", id) + } + if id == p.id { + continue // avoid self-edge + } + imports = append(imports, pkg2) + } + sort.Sort(byPath(imports)) + pkg.SetImports(imports) + + // package was imported completely and without errors + pkg.MarkComplete() + + return pkg +} + +type byPath []*types.Package + +func (a byPath) Len() int { return len(a) } +func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go new file mode 100644 index 0000000..4be32a2 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go @@ -0,0 +1,739 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed binary package export. +// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go; +// see that file for specification of the format. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "go/ast" + "go/constant" + "go/token" + "go/types" + "io" + "math/big" + "reflect" + "sort" +) + +// Current indexed export format version. Increase with each format change. +// 0: Go1.11 encoding +const iexportVersion = 0 + +// IExportData returns the binary export data for pkg. +// +// If no file set is provided, position info will be missing. +// The package path of the top-level package will not be recorded, +// so that calls to IImportData can override with a provided package path. +func IExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) { + defer func() { + if e := recover(); e != nil { + if ierr, ok := e.(internalError); ok { + err = ierr + return + } + // Not an internal error; panic again. + panic(e) + } + }() + + p := iexporter{ + out: bytes.NewBuffer(nil), + fset: fset, + allPkgs: map[*types.Package]bool{}, + stringIndex: map[string]uint64{}, + declIndex: map[types.Object]uint64{}, + typIndex: map[types.Type]uint64{}, + localpkg: pkg, + } + + for i, pt := range predeclared() { + p.typIndex[pt] = uint64(i) + } + if len(p.typIndex) > predeclReserved { + panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) + } + + // Initialize work queue with exported declarations. + scope := pkg.Scope() + for _, name := range scope.Names() { + if ast.IsExported(name) { + p.pushDecl(scope.Lookup(name)) + } + } + + // Loop until no more work. + for !p.declTodo.empty() { + p.doDecl(p.declTodo.popHead()) + } + + // Append indices to data0 section. + dataLen := uint64(p.data0.Len()) + w := p.newWriter() + w.writeIndex(p.declIndex) + w.flush() + + // Assemble header. + var hdr intWriter + hdr.WriteByte('i') + hdr.uint64(iexportVersion) + hdr.uint64(uint64(p.strings.Len())) + hdr.uint64(dataLen) + + // Flush output. + io.Copy(p.out, &hdr) + io.Copy(p.out, &p.strings) + io.Copy(p.out, &p.data0) + + return p.out.Bytes(), nil +} + +// writeIndex writes out an object index. mainIndex indicates whether +// we're writing out the main index, which is also read by +// non-compiler tools and includes a complete package description +// (i.e., name and height). +func (w *exportWriter) writeIndex(index map[types.Object]uint64) { + // Build a map from packages to objects from that package. + pkgObjs := map[*types.Package][]types.Object{} + + // For the main index, make sure to include every package that + // we reference, even if we're not exporting (or reexporting) + // any symbols from it. + pkgObjs[w.p.localpkg] = nil + for pkg := range w.p.allPkgs { + pkgObjs[pkg] = nil + } + + for obj := range index { + pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj) + } + + var pkgs []*types.Package + for pkg, objs := range pkgObjs { + pkgs = append(pkgs, pkg) + + sort.Slice(objs, func(i, j int) bool { + return objs[i].Name() < objs[j].Name() + }) + } + + sort.Slice(pkgs, func(i, j int) bool { + return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) + }) + + w.uint64(uint64(len(pkgs))) + for _, pkg := range pkgs { + w.string(w.exportPath(pkg)) + w.string(pkg.Name()) + w.uint64(uint64(0)) // package height is not needed for go/types + + objs := pkgObjs[pkg] + w.uint64(uint64(len(objs))) + for _, obj := range objs { + w.string(obj.Name()) + w.uint64(index[obj]) + } + } +} + +type iexporter struct { + fset *token.FileSet + out *bytes.Buffer + + localpkg *types.Package + + // allPkgs tracks all packages that have been referenced by + // the export data, so we can ensure to include them in the + // main index. + allPkgs map[*types.Package]bool + + declTodo objQueue + + strings intWriter + stringIndex map[string]uint64 + + data0 intWriter + declIndex map[types.Object]uint64 + typIndex map[types.Type]uint64 +} + +// stringOff returns the offset of s within the string section. +// If not already present, it's added to the end. +func (p *iexporter) stringOff(s string) uint64 { + off, ok := p.stringIndex[s] + if !ok { + off = uint64(p.strings.Len()) + p.stringIndex[s] = off + + p.strings.uint64(uint64(len(s))) + p.strings.WriteString(s) + } + return off +} + +// pushDecl adds n to the declaration work queue, if not already present. +func (p *iexporter) pushDecl(obj types.Object) { + // Package unsafe is known to the compiler and predeclared. + assert(obj.Pkg() != types.Unsafe) + + if _, ok := p.declIndex[obj]; ok { + return + } + + p.declIndex[obj] = ^uint64(0) // mark n present in work queue + p.declTodo.pushTail(obj) +} + +// exportWriter handles writing out individual data section chunks. +type exportWriter struct { + p *iexporter + + data intWriter + currPkg *types.Package + prevFile string + prevLine int64 +} + +func (w *exportWriter) exportPath(pkg *types.Package) string { + if pkg == w.p.localpkg { + return "" + } + return pkg.Path() +} + +func (p *iexporter) doDecl(obj types.Object) { + w := p.newWriter() + w.setPkg(obj.Pkg(), false) + + switch obj := obj.(type) { + case *types.Var: + w.tag('V') + w.pos(obj.Pos()) + w.typ(obj.Type(), obj.Pkg()) + + case *types.Func: + sig, _ := obj.Type().(*types.Signature) + if sig.Recv() != nil { + panic(internalErrorf("unexpected method: %v", sig)) + } + w.tag('F') + w.pos(obj.Pos()) + w.signature(sig) + + case *types.Const: + w.tag('C') + w.pos(obj.Pos()) + w.value(obj.Type(), obj.Val()) + + case *types.TypeName: + if obj.IsAlias() { + w.tag('A') + w.pos(obj.Pos()) + w.typ(obj.Type(), obj.Pkg()) + break + } + + // Defined type. + w.tag('T') + w.pos(obj.Pos()) + + underlying := obj.Type().Underlying() + w.typ(underlying, obj.Pkg()) + + t := obj.Type() + if types.IsInterface(t) { + break + } + + named, ok := t.(*types.Named) + if !ok { + panic(internalErrorf("%s is not a defined type", t)) + } + + n := named.NumMethods() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + m := named.Method(i) + w.pos(m.Pos()) + w.string(m.Name()) + sig, _ := m.Type().(*types.Signature) + w.param(sig.Recv()) + w.signature(sig) + } + + default: + panic(internalErrorf("unexpected object: %v", obj)) + } + + p.declIndex[obj] = w.flush() +} + +func (w *exportWriter) tag(tag byte) { + w.data.WriteByte(tag) +} + +func (w *exportWriter) pos(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + + // When file is the same as the last position (common case), + // we can save a few bytes by delta encoding just the line + // number. + // + // Note: Because data objects may be read out of order (or not + // at all), we can only apply delta encoding within a single + // object. This is handled implicitly by tracking prevFile and + // prevLine as fields of exportWriter. + + if file == w.prevFile { + delta := line - w.prevLine + w.int64(delta) + if delta == deltaNewFile { + w.int64(-1) + } + } else { + w.int64(deltaNewFile) + w.int64(line) // line >= 0 + w.string(file) + w.prevFile = file + } + w.prevLine = line +} + +func (w *exportWriter) pkg(pkg *types.Package) { + // Ensure any referenced packages are declared in the main index. + w.p.allPkgs[pkg] = true + + w.string(w.exportPath(pkg)) +} + +func (w *exportWriter) qualifiedIdent(obj types.Object) { + // Ensure any referenced declarations are written out too. + w.p.pushDecl(obj) + + w.string(obj.Name()) + w.pkg(obj.Pkg()) +} + +func (w *exportWriter) typ(t types.Type, pkg *types.Package) { + w.data.uint64(w.p.typOff(t, pkg)) +} + +func (p *iexporter) newWriter() *exportWriter { + return &exportWriter{p: p} +} + +func (w *exportWriter) flush() uint64 { + off := uint64(w.p.data0.Len()) + io.Copy(&w.p.data0, &w.data) + return off +} + +func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { + off, ok := p.typIndex[t] + if !ok { + w := p.newWriter() + w.doTyp(t, pkg) + off = predeclReserved + w.flush() + p.typIndex[t] = off + } + return off +} + +func (w *exportWriter) startType(k itag) { + w.data.uint64(uint64(k)) +} + +func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { + switch t := t.(type) { + case *types.Named: + w.startType(definedType) + w.qualifiedIdent(t.Obj()) + + case *types.Pointer: + w.startType(pointerType) + w.typ(t.Elem(), pkg) + + case *types.Slice: + w.startType(sliceType) + w.typ(t.Elem(), pkg) + + case *types.Array: + w.startType(arrayType) + w.uint64(uint64(t.Len())) + w.typ(t.Elem(), pkg) + + case *types.Chan: + w.startType(chanType) + // 1 RecvOnly; 2 SendOnly; 3 SendRecv + var dir uint64 + switch t.Dir() { + case types.RecvOnly: + dir = 1 + case types.SendOnly: + dir = 2 + case types.SendRecv: + dir = 3 + } + w.uint64(dir) + w.typ(t.Elem(), pkg) + + case *types.Map: + w.startType(mapType) + w.typ(t.Key(), pkg) + w.typ(t.Elem(), pkg) + + case *types.Signature: + w.startType(signatureType) + w.setPkg(pkg, true) + w.signature(t) + + case *types.Struct: + w.startType(structType) + w.setPkg(pkg, true) + + n := t.NumFields() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + f := t.Field(i) + w.pos(f.Pos()) + w.string(f.Name()) + w.typ(f.Type(), pkg) + w.bool(f.Anonymous()) + w.string(t.Tag(i)) // note (or tag) + } + + case *types.Interface: + w.startType(interfaceType) + w.setPkg(pkg, true) + + n := t.NumEmbeddeds() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + f := t.Embedded(i) + w.pos(f.Obj().Pos()) + w.typ(f.Obj().Type(), f.Obj().Pkg()) + } + + n = t.NumExplicitMethods() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + m := t.ExplicitMethod(i) + w.pos(m.Pos()) + w.string(m.Name()) + sig, _ := m.Type().(*types.Signature) + w.signature(sig) + } + + default: + panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) + } +} + +func (w *exportWriter) setPkg(pkg *types.Package, write bool) { + if write { + w.pkg(pkg) + } + + w.currPkg = pkg +} + +func (w *exportWriter) signature(sig *types.Signature) { + w.paramList(sig.Params()) + w.paramList(sig.Results()) + if sig.Params().Len() > 0 { + w.bool(sig.Variadic()) + } +} + +func (w *exportWriter) paramList(tup *types.Tuple) { + n := tup.Len() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + w.param(tup.At(i)) + } +} + +func (w *exportWriter) param(obj types.Object) { + w.pos(obj.Pos()) + w.localIdent(obj) + w.typ(obj.Type(), obj.Pkg()) +} + +func (w *exportWriter) value(typ types.Type, v constant.Value) { + w.typ(typ, nil) + + switch v.Kind() { + case constant.Bool: + w.bool(constant.BoolVal(v)) + case constant.Int: + var i big.Int + if i64, exact := constant.Int64Val(v); exact { + i.SetInt64(i64) + } else if ui64, exact := constant.Uint64Val(v); exact { + i.SetUint64(ui64) + } else { + i.SetString(v.ExactString(), 10) + } + w.mpint(&i, typ) + case constant.Float: + f := constantToFloat(v) + w.mpfloat(f, typ) + case constant.Complex: + w.mpfloat(constantToFloat(constant.Real(v)), typ) + w.mpfloat(constantToFloat(constant.Imag(v)), typ) + case constant.String: + w.string(constant.StringVal(v)) + case constant.Unknown: + // package contains type errors + default: + panic(internalErrorf("unexpected value %v (%T)", v, v)) + } +} + +// constantToFloat converts a constant.Value with kind constant.Float to a +// big.Float. +func constantToFloat(x constant.Value) *big.Float { + assert(x.Kind() == constant.Float) + // Use the same floating-point precision (512) as cmd/compile + // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). + const mpprec = 512 + var f big.Float + f.SetPrec(mpprec) + if v, exact := constant.Float64Val(x); exact { + // float64 + f.SetFloat64(v) + } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { + // TODO(gri): add big.Rat accessor to constant.Value. + n := valueToRat(num) + d := valueToRat(denom) + f.SetRat(n.Quo(n, d)) + } else { + // Value too large to represent as a fraction => inaccessible. + // TODO(gri): add big.Float accessor to constant.Value. + _, ok := f.SetString(x.ExactString()) + assert(ok) + } + return &f +} + +// mpint exports a multi-precision integer. +// +// For unsigned types, small values are written out as a single +// byte. Larger values are written out as a length-prefixed big-endian +// byte string, where the length prefix is encoded as its complement. +// For example, bytes 0, 1, and 2 directly represent the integer +// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, +// 2-, and 3-byte big-endian string follow. +// +// Encoding for signed types use the same general approach as for +// unsigned types, except small values use zig-zag encoding and the +// bottom bit of length prefix byte for large values is reserved as a +// sign bit. +// +// The exact boundary between small and large encodings varies +// according to the maximum number of bytes needed to encode a value +// of type typ. As a special case, 8-bit types are always encoded as a +// single byte. +// +// TODO(mdempsky): Is this level of complexity really worthwhile? +func (w *exportWriter) mpint(x *big.Int, typ types.Type) { + basic, ok := typ.Underlying().(*types.Basic) + if !ok { + panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) + } + + signed, maxBytes := intSize(basic) + + negative := x.Sign() < 0 + if !signed && negative { + panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) + } + + b := x.Bytes() + if len(b) > 0 && b[0] == 0 { + panic(internalErrorf("leading zeros")) + } + if uint(len(b)) > maxBytes { + panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) + } + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + // Check if x can use small value encoding. + if len(b) <= 1 { + var ux uint + if len(b) == 1 { + ux = uint(b[0]) + } + if signed { + ux <<= 1 + if negative { + ux-- + } + } + if ux < maxSmall { + w.data.WriteByte(byte(ux)) + return + } + } + + n := 256 - uint(len(b)) + if signed { + n = 256 - 2*uint(len(b)) + if negative { + n |= 1 + } + } + if n < maxSmall || n >= 256 { + panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) + } + + w.data.WriteByte(byte(n)) + w.data.Write(b) +} + +// mpfloat exports a multi-precision floating point number. +// +// The number's value is decomposed into mantissa × 2**exponent, where +// mantissa is an integer. The value is written out as mantissa (as a +// multi-precision integer) and then the exponent, except exponent is +// omitted if mantissa is zero. +func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { + if f.IsInf() { + panic("infinite constant") + } + + // Break into f = mant × 2**exp, with 0.5 <= mant < 1. + var mant big.Float + exp := int64(f.MantExp(&mant)) + + // Scale so that mant is an integer. + prec := mant.MinPrec() + mant.SetMantExp(&mant, int(prec)) + exp -= int64(prec) + + manti, acc := mant.Int(nil) + if acc != big.Exact { + panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) + } + w.mpint(manti, typ) + if manti.Sign() != 0 { + w.int64(exp) + } +} + +func (w *exportWriter) bool(b bool) bool { + var x uint64 + if b { + x = 1 + } + w.uint64(x) + return b +} + +func (w *exportWriter) int64(x int64) { w.data.int64(x) } +func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } +func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } + +func (w *exportWriter) localIdent(obj types.Object) { + // Anonymous parameters. + if obj == nil { + w.string("") + return + } + + name := obj.Name() + if name == "_" { + w.string("_") + return + } + + w.string(name) +} + +type intWriter struct { + bytes.Buffer +} + +func (w *intWriter) int64(x int64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutVarint(buf[:], x) + w.Write(buf[:n]) +} + +func (w *intWriter) uint64(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + w.Write(buf[:n]) +} + +func assert(cond bool) { + if !cond { + panic("internal error: assertion failed") + } +} + +// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. + +// objQueue is a FIFO queue of types.Object. The zero value of objQueue is +// a ready-to-use empty queue. +type objQueue struct { + ring []types.Object + head, tail int +} + +// empty returns true if q contains no Nodes. +func (q *objQueue) empty() bool { + return q.head == q.tail +} + +// pushTail appends n to the tail of the queue. +func (q *objQueue) pushTail(obj types.Object) { + if len(q.ring) == 0 { + q.ring = make([]types.Object, 16) + } else if q.head+len(q.ring) == q.tail { + // Grow the ring. + nring := make([]types.Object, len(q.ring)*2) + // Copy the old elements. + part := q.ring[q.head%len(q.ring):] + if q.tail-q.head <= len(part) { + part = part[:q.tail-q.head] + copy(nring, part) + } else { + pos := copy(nring, part) + copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) + } + q.ring, q.head, q.tail = nring, 0, q.tail-q.head + } + + q.ring[q.tail%len(q.ring)] = obj + q.tail++ +} + +// popHead pops a node from the head of the queue. It panics if q is empty. +func (q *objQueue) popHead() types.Object { + if q.empty() { + panic("dequeue empty") + } + obj := q.ring[q.head%len(q.ring)] + q.head++ + return obj +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go new file mode 100644 index 0000000..a31a880 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -0,0 +1,630 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed package import. +// See cmd/compile/internal/gc/iexport.go for the export data format. + +// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "io" + "sort" +) + +type intReader struct { + *bytes.Reader + path string +} + +func (r *intReader) int64() int64 { + i, err := binary.ReadVarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +func (r *intReader) uint64() uint64 { + i, err := binary.ReadUvarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +const predeclReserved = 32 + +type itag uint64 + +const ( + // Types + definedType itag = iota + pointerType + sliceType + arrayType + chanType + mapType + signatureType + structType + interfaceType +) + +// IImportData imports a package from the serialized package data +// and returns the number of bytes consumed and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + const currentVersion = 1 + version := int64(-1) + defer func() { + if e := recover(); e != nil { + if version > currentVersion { + err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) + } else { + err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) + } + } + }() + + r := &intReader{bytes.NewReader(data), path} + + version = int64(r.uint64()) + switch version { + case currentVersion, 0: + default: + errorf("unknown iexport format version %d", version) + } + + sLen := int64(r.uint64()) + dLen := int64(r.uint64()) + + whence, _ := r.Seek(0, io.SeekCurrent) + stringData := data[whence : whence+sLen] + declData := data[whence+sLen : whence+sLen+dLen] + r.Seek(sLen+dLen, io.SeekCurrent) + + p := iimporter{ + ipath: path, + version: int(version), + + stringData: stringData, + stringCache: make(map[uint64]string), + pkgCache: make(map[uint64]*types.Package), + + declData: declData, + pkgIndex: make(map[*types.Package]map[string]uint64), + typCache: make(map[uint64]types.Type), + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*token.File), + }, + } + + for i, pt := range predeclared() { + p.typCache[uint64(i)] = pt + } + + pkgList := make([]*types.Package, r.uint64()) + for i := range pkgList { + pkgPathOff := r.uint64() + pkgPath := p.stringAt(pkgPathOff) + pkgName := p.stringAt(r.uint64()) + _ = r.uint64() // package height; unused by go/types + + if pkgPath == "" { + pkgPath = path + } + pkg := imports[pkgPath] + if pkg == nil { + pkg = types.NewPackage(pkgPath, pkgName) + imports[pkgPath] = pkg + } else if pkg.Name() != pkgName { + errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path) + } + + p.pkgCache[pkgPathOff] = pkg + + nameIndex := make(map[string]uint64) + for nSyms := r.uint64(); nSyms > 0; nSyms-- { + name := p.stringAt(r.uint64()) + nameIndex[name] = r.uint64() + } + + p.pkgIndex[pkg] = nameIndex + pkgList[i] = pkg + } + if len(pkgList) == 0 { + errorf("no packages found for %s", path) + panic("unreachable") + } + p.ipkg = pkgList[0] + names := make([]string, 0, len(p.pkgIndex[p.ipkg])) + for name := range p.pkgIndex[p.ipkg] { + names = append(names, name) + } + sort.Strings(names) + for _, name := range names { + p.doDecl(p.ipkg, name) + } + + for _, typ := range p.interfaceList { + typ.Complete() + } + + // record all referenced packages as imports + list := append(([]*types.Package)(nil), pkgList[1:]...) + sort.Sort(byPath(list)) + p.ipkg.SetImports(list) + + // package was imported completely and without errors + p.ipkg.MarkComplete() + + consumed, _ := r.Seek(0, io.SeekCurrent) + return int(consumed), p.ipkg, nil +} + +type iimporter struct { + ipath string + ipkg *types.Package + version int + + stringData []byte + stringCache map[uint64]string + pkgCache map[uint64]*types.Package + + declData []byte + pkgIndex map[*types.Package]map[string]uint64 + typCache map[uint64]types.Type + + fake fakeFileSet + interfaceList []*types.Interface +} + +func (p *iimporter) doDecl(pkg *types.Package, name string) { + // See if we've already imported this declaration. + if obj := pkg.Scope().Lookup(name); obj != nil { + return + } + + off, ok := p.pkgIndex[pkg][name] + if !ok { + errorf("%v.%v not in index", pkg, name) + } + + r := &importReader{p: p, currPkg: pkg} + r.declReader.Reset(p.declData[off:]) + + r.obj(name) +} + +func (p *iimporter) stringAt(off uint64) string { + if s, ok := p.stringCache[off]; ok { + return s + } + + slen, n := binary.Uvarint(p.stringData[off:]) + if n <= 0 { + errorf("varint failed") + } + spos := off + uint64(n) + s := string(p.stringData[spos : spos+slen]) + p.stringCache[off] = s + return s +} + +func (p *iimporter) pkgAt(off uint64) *types.Package { + if pkg, ok := p.pkgCache[off]; ok { + return pkg + } + path := p.stringAt(off) + if path == p.ipath { + return p.ipkg + } + errorf("missing package %q in %q", path, p.ipath) + return nil +} + +func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { + if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { + return t + } + + if off < predeclReserved { + errorf("predeclared type missing from cache: %v", off) + } + + r := &importReader{p: p} + r.declReader.Reset(p.declData[off-predeclReserved:]) + t := r.doType(base) + + if base == nil || !isInterface(t) { + p.typCache[off] = t + } + return t +} + +type importReader struct { + p *iimporter + declReader bytes.Reader + currPkg *types.Package + prevFile string + prevLine int64 + prevColumn int64 +} + +func (r *importReader) obj(name string) { + tag := r.byte() + pos := r.pos() + + switch tag { + case 'A': + typ := r.typ() + + r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) + + case 'C': + typ, val := r.value() + + r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) + + case 'F': + sig := r.signature(nil) + + r.declare(types.NewFunc(pos, r.currPkg, name, sig)) + + case 'T': + // Types can be recursive. We need to setup a stub + // declaration before recursing. + obj := types.NewTypeName(pos, r.currPkg, name, nil) + named := types.NewNamed(obj, nil, nil) + r.declare(obj) + + underlying := r.p.typAt(r.uint64(), named).Underlying() + named.SetUnderlying(underlying) + + if !isInterface(underlying) { + for n := r.uint64(); n > 0; n-- { + mpos := r.pos() + mname := r.ident() + recv := r.param() + msig := r.signature(recv) + + named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) + } + } + + case 'V': + typ := r.typ() + + r.declare(types.NewVar(pos, r.currPkg, name, typ)) + + default: + errorf("unexpected tag: %v", tag) + } +} + +func (r *importReader) declare(obj types.Object) { + obj.Pkg().Scope().Insert(obj) +} + +func (r *importReader) value() (typ types.Type, val constant.Value) { + typ = r.typ() + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + val = constant.MakeBool(r.bool()) + + case types.IsString: + val = constant.MakeString(r.string()) + + case types.IsInteger: + val = r.mpint(b) + + case types.IsFloat: + val = r.mpfloat(b) + + case types.IsComplex: + re := r.mpfloat(b) + im := r.mpfloat(b) + val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + + default: + if b.Kind() == types.Invalid { + val = constant.MakeUnknown() + return + } + errorf("unexpected type %v", typ) // panics + panic("unreachable") + } + + return +} + +func intSize(b *types.Basic) (signed bool, maxBytes uint) { + if (b.Info() & types.IsUntyped) != 0 { + return true, 64 + } + + switch b.Kind() { + case types.Float32, types.Complex64: + return true, 3 + case types.Float64, types.Complex128: + return true, 7 + } + + signed = (b.Info() & types.IsUnsigned) == 0 + switch b.Kind() { + case types.Int8, types.Uint8: + maxBytes = 1 + case types.Int16, types.Uint16: + maxBytes = 2 + case types.Int32, types.Uint32: + maxBytes = 4 + default: + maxBytes = 8 + } + + return +} + +func (r *importReader) mpint(b *types.Basic) constant.Value { + signed, maxBytes := intSize(b) + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + n, _ := r.declReader.ReadByte() + if uint(n) < maxSmall { + v := int64(n) + if signed { + v >>= 1 + if n&1 != 0 { + v = ^v + } + } + return constant.MakeInt64(v) + } + + v := -n + if signed { + v = -(n &^ 1) >> 1 + } + if v < 1 || uint(v) > maxBytes { + errorf("weird decoding: %v, %v => %v", n, signed, v) + } + + buf := make([]byte, v) + io.ReadFull(&r.declReader, buf) + + // convert to little endian + // TODO(gri) go/constant should have a more direct conversion function + // (e.g., once it supports a big.Float based implementation) + for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { + buf[i], buf[j] = buf[j], buf[i] + } + + x := constant.MakeFromBytes(buf) + if signed && n&1 != 0 { + x = constant.UnaryOp(token.SUB, x, 0) + } + return x +} + +func (r *importReader) mpfloat(b *types.Basic) constant.Value { + x := r.mpint(b) + if constant.Sign(x) == 0 { + return x + } + + exp := r.int64() + switch { + case exp > 0: + x = constant.Shift(x, token.SHL, uint(exp)) + case exp < 0: + d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) + x = constant.BinaryOp(x, token.QUO, d) + } + return x +} + +func (r *importReader) ident() string { + return r.string() +} + +func (r *importReader) qualifiedIdent() (*types.Package, string) { + name := r.string() + pkg := r.pkg() + return pkg, name +} + +func (r *importReader) pos() token.Pos { + if r.p.version >= 1 { + r.posv1() + } else { + r.posv0() + } + + if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { + return token.NoPos + } + return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) +} + +func (r *importReader) posv0() { + delta := r.int64() + if delta != deltaNewFile { + r.prevLine += delta + } else if l := r.int64(); l == -1 { + r.prevLine += deltaNewFile + } else { + r.prevFile = r.string() + r.prevLine = l + } +} + +func (r *importReader) posv1() { + delta := r.int64() + r.prevColumn += delta >> 1 + if delta&1 != 0 { + delta = r.int64() + r.prevLine += delta >> 1 + if delta&1 != 0 { + r.prevFile = r.string() + } + } +} + +func (r *importReader) typ() types.Type { + return r.p.typAt(r.uint64(), nil) +} + +func isInterface(t types.Type) bool { + _, ok := t.(*types.Interface) + return ok +} + +func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } +func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } + +func (r *importReader) doType(base *types.Named) types.Type { + switch k := r.kind(); k { + default: + errorf("unexpected kind tag in %q: %v", r.p.ipath, k) + return nil + + case definedType: + pkg, name := r.qualifiedIdent() + r.p.doDecl(pkg, name) + return pkg.Scope().Lookup(name).(*types.TypeName).Type() + case pointerType: + return types.NewPointer(r.typ()) + case sliceType: + return types.NewSlice(r.typ()) + case arrayType: + n := r.uint64() + return types.NewArray(r.typ(), int64(n)) + case chanType: + dir := chanDir(int(r.uint64())) + return types.NewChan(dir, r.typ()) + case mapType: + return types.NewMap(r.typ(), r.typ()) + case signatureType: + r.currPkg = r.pkg() + return r.signature(nil) + + case structType: + r.currPkg = r.pkg() + + fields := make([]*types.Var, r.uint64()) + tags := make([]string, len(fields)) + for i := range fields { + fpos := r.pos() + fname := r.ident() + ftyp := r.typ() + emb := r.bool() + tag := r.string() + + fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb) + tags[i] = tag + } + return types.NewStruct(fields, tags) + + case interfaceType: + r.currPkg = r.pkg() + + embeddeds := make([]types.Type, r.uint64()) + for i := range embeddeds { + _ = r.pos() + embeddeds[i] = r.typ() + } + + methods := make([]*types.Func, r.uint64()) + for i := range methods { + mpos := r.pos() + mname := r.ident() + + // TODO(mdempsky): Matches bimport.go, but I + // don't agree with this. + var recv *types.Var + if base != nil { + recv = types.NewVar(token.NoPos, r.currPkg, "", base) + } + + msig := r.signature(recv) + methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) + } + + typ := newInterface(methods, embeddeds) + r.p.interfaceList = append(r.p.interfaceList, typ) + return typ + } +} + +func (r *importReader) kind() itag { + return itag(r.uint64()) +} + +func (r *importReader) signature(recv *types.Var) *types.Signature { + params := r.paramList() + results := r.paramList() + variadic := params.Len() > 0 && r.bool() + return types.NewSignature(recv, params, results, variadic) +} + +func (r *importReader) paramList() *types.Tuple { + xs := make([]*types.Var, r.uint64()) + for i := range xs { + xs[i] = r.param() + } + return types.NewTuple(xs...) +} + +func (r *importReader) param() *types.Var { + pos := r.pos() + name := r.ident() + typ := r.typ() + return types.NewParam(pos, r.currPkg, name, typ) +} + +func (r *importReader) bool() bool { + return r.uint64() != 0 +} + +func (r *importReader) int64() int64 { + n, err := binary.ReadVarint(&r.declReader) + if err != nil { + errorf("readVarint: %v", err) + } + return n +} + +func (r *importReader) uint64() uint64 { + n, err := binary.ReadUvarint(&r.declReader) + if err != nil { + errorf("readUvarint: %v", err) + } + return n +} + +func (r *importReader) byte() byte { + x, err := r.declReader.ReadByte() + if err != nil { + errorf("declReader.ReadByte: %v", err) + } + return x +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go new file mode 100644 index 0000000..463f252 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.11 + +package gcimporter + +import "go/types" + +func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { + named := make([]*types.Named, len(embeddeds)) + for i, e := range embeddeds { + var ok bool + named[i], ok = e.(*types.Named) + if !ok { + panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") + } + } + return types.NewInterface(methods, named) +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go new file mode 100644 index 0000000..ab28b95 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 + +package gcimporter + +import "go/types" + +func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { + return types.NewInterfaceType(methods, embeddeds) +} diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go new file mode 100644 index 0000000..dc6177c --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go @@ -0,0 +1,117 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package packagesdriver fetches type sizes for go/packages and go/analysis. +package packagesdriver + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "go/types" + "os/exec" + "strings" + + "golang.org/x/tools/internal/gocommand" +) + +var debug = false + +func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) { + // TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver. + const toolPrefix = "GOPACKAGESDRIVER=" + tool := "" + for _, env := range env { + if val := strings.TrimPrefix(env, toolPrefix); val != env { + tool = val + } + } + + if tool == "" { + var err error + tool, err = exec.LookPath("gopackagesdriver") + if err != nil { + // We did not find the driver, so use "go list". + tool = "off" + } + } + + if tool == "off" { + return GetSizesGolist(ctx, buildFlags, env, gocmdRunner, dir) + } + + req, err := json.Marshal(struct { + Command string `json:"command"` + Env []string `json:"env"` + BuildFlags []string `json:"build_flags"` + }{ + Command: "sizes", + Env: env, + BuildFlags: buildFlags, + }) + if err != nil { + return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) + } + + buf := new(bytes.Buffer) + cmd := exec.CommandContext(ctx, tool) + cmd.Dir = dir + cmd.Env = env + cmd.Stdin = bytes.NewReader(req) + cmd.Stdout = buf + cmd.Stderr = new(bytes.Buffer) + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) + } + var response struct { + // Sizes, if not nil, is the types.Sizes to use when type checking. + Sizes *types.StdSizes + } + if err := json.Unmarshal(buf.Bytes(), &response); err != nil { + return nil, err + } + return response.Sizes, nil +} + +func GetSizesGolist(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) { + inv := gocommand.Invocation{ + Verb: "list", + Args: []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}, + Env: env, + BuildFlags: buildFlags, + WorkingDir: dir, + } + stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) + var goarch, compiler string + if rawErr != nil { + if strings.Contains(rawErr.Error(), "cannot find main module") { + // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc. + // TODO(matloob): Is this a problem in practice? + inv := gocommand.Invocation{ + Verb: "env", + Args: []string{"GOARCH"}, + Env: env, + WorkingDir: dir, + } + envout, enverr := gocmdRunner.Run(ctx, inv) + if enverr != nil { + return nil, enverr + } + goarch = strings.TrimSpace(envout.String()) + compiler = "gc" + } else { + return nil, friendlyErr + } + } else { + fields := strings.Fields(stdout.String()) + if len(fields) < 2 { + return nil, fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", + stdout.String(), stderr.String()) + } + goarch = fields[0] + compiler = fields[1] + } + return types.SizesFor(compiler, goarch), nil +} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go new file mode 100644 index 0000000..4bfe28a --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/doc.go @@ -0,0 +1,221 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package packages loads Go packages for inspection and analysis. + +The Load function takes as input a list of patterns and return a list of Package +structs describing individual packages matched by those patterns. +The LoadMode controls the amount of detail in the loaded packages. + +Load passes most patterns directly to the underlying build tool, +but all patterns with the prefix "query=", where query is a +non-empty string of letters from [a-z], are reserved and may be +interpreted as query operators. + +Two query operators are currently supported: "file" and "pattern". + +The query "file=path/to/file.go" matches the package or packages enclosing +the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" +might return the packages "fmt" and "fmt [fmt.test]". + +The query "pattern=string" causes "string" to be passed directly to +the underlying build tool. In most cases this is unnecessary, +but an application can use Load("pattern=" + x) as an escaping mechanism +to ensure that x is not interpreted as a query operator if it contains '='. + +All other query operators are reserved for future use and currently +cause Load to report an error. + +The Package struct provides basic information about the package, including + + - ID, a unique identifier for the package in the returned set; + - GoFiles, the names of the package's Go source files; + - Imports, a map from source import strings to the Packages they name; + - Types, the type information for the package's exported symbols; + - Syntax, the parsed syntax trees for the package's source code; and + - TypeInfo, the result of a complete type-check of the package syntax trees. + +(See the documentation for type Package for the complete list of fields +and more detailed descriptions.) + +For example, + + Load(nil, "bytes", "unicode...") + +returns four Package structs describing the standard library packages +bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern +can match multiple packages and that a package might be matched by +multiple patterns: in general it is not possible to determine which +packages correspond to which patterns. + +Note that the list returned by Load contains only the packages matched +by the patterns. Their dependencies can be found by walking the import +graph using the Imports fields. + +The Load function can be configured by passing a pointer to a Config as +the first argument. A nil Config is equivalent to the zero Config, which +causes Load to run in LoadFiles mode, collecting minimal information. +See the documentation for type Config for details. + +As noted earlier, the Config.Mode controls the amount of detail +reported about the loaded packages. See the documentation for type LoadMode +for details. + +Most tools should pass their command-line arguments (after any flags) +uninterpreted to the loader, so that the loader can interpret them +according to the conventions of the underlying build system. +See the Example function for typical usage. + +*/ +package packages // import "golang.org/x/tools/go/packages" + +/* + +Motivation and design considerations + +The new package's design solves problems addressed by two existing +packages: go/build, which locates and describes packages, and +golang.org/x/tools/go/loader, which loads, parses and type-checks them. +The go/build.Package structure encodes too much of the 'go build' way +of organizing projects, leaving us in need of a data type that describes a +package of Go source code independent of the underlying build system. +We wanted something that works equally well with go build and vgo, and +also other build systems such as Bazel and Blaze, making it possible to +construct analysis tools that work in all these environments. +Tools such as errcheck and staticcheck were essentially unavailable to +the Go community at Google, and some of Google's internal tools for Go +are unavailable externally. +This new package provides a uniform way to obtain package metadata by +querying each of these build systems, optionally supporting their +preferred command-line notations for packages, so that tools integrate +neatly with users' build environments. The Metadata query function +executes an external query tool appropriate to the current workspace. + +Loading packages always returns the complete import graph "all the way down", +even if all you want is information about a single package, because the query +mechanisms of all the build systems we currently support ({go,vgo} list, and +blaze/bazel aspect-based query) cannot provide detailed information +about one package without visiting all its dependencies too, so there is +no additional asymptotic cost to providing transitive information. +(This property might not be true of a hypothetical 5th build system.) + +In calls to TypeCheck, all initial packages, and any package that +transitively depends on one of them, must be loaded from source. +Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from +source; D may be loaded from export data, and E may not be loaded at all +(though it's possible that D's export data mentions it, so a +types.Package may be created for it and exposed.) + +The old loader had a feature to suppress type-checking of function +bodies on a per-package basis, primarily intended to reduce the work of +obtaining type information for imported packages. Now that imports are +satisfied by export data, the optimization no longer seems necessary. + +Despite some early attempts, the old loader did not exploit export data, +instead always using the equivalent of WholeProgram mode. This was due +to the complexity of mixing source and export data packages (now +resolved by the upward traversal mentioned above), and because export data +files were nearly always missing or stale. Now that 'go build' supports +caching, all the underlying build systems can guarantee to produce +export data in a reasonable (amortized) time. + +Test "main" packages synthesized by the build system are now reported as +first-class packages, avoiding the need for clients (such as go/ssa) to +reinvent this generation logic. + +One way in which go/packages is simpler than the old loader is in its +treatment of in-package tests. In-package tests are packages that +consist of all the files of the library under test, plus the test files. +The old loader constructed in-package tests by a two-phase process of +mutation called "augmentation": first it would construct and type check +all the ordinary library packages and type-check the packages that +depend on them; then it would add more (test) files to the package and +type-check again. This two-phase approach had four major problems: +1) in processing the tests, the loader modified the library package, + leaving no way for a client application to see both the test + package and the library package; one would mutate into the other. +2) because test files can declare additional methods on types defined in + the library portion of the package, the dispatch of method calls in + the library portion was affected by the presence of the test files. + This should have been a clue that the packages were logically + different. +3) this model of "augmentation" assumed at most one in-package test + per library package, which is true of projects using 'go build', + but not other build systems. +4) because of the two-phase nature of test processing, all packages that + import the library package had to be processed before augmentation, + forcing a "one-shot" API and preventing the client from calling Load + in several times in sequence as is now possible in WholeProgram mode. + (TypeCheck mode has a similar one-shot restriction for a different reason.) + +Early drafts of this package supported "multi-shot" operation. +Although it allowed clients to make a sequence of calls (or concurrent +calls) to Load, building up the graph of Packages incrementally, +it was of marginal value: it complicated the API +(since it allowed some options to vary across calls but not others), +it complicated the implementation, +it cannot be made to work in Types mode, as explained above, +and it was less efficient than making one combined call (when this is possible). +Among the clients we have inspected, none made multiple calls to load +but could not be easily and satisfactorily modified to make only a single call. +However, applications changes may be required. +For example, the ssadump command loads the user-specified packages +and in addition the runtime package. It is tempting to simply append +"runtime" to the user-provided list, but that does not work if the user +specified an ad-hoc package such as [a.go b.go]. +Instead, ssadump no longer requests the runtime package, +but seeks it among the dependencies of the user-specified packages, +and emits an error if it is not found. + +Overlays: The Overlay field in the Config allows providing alternate contents +for Go source files, by providing a mapping from file path to contents. +go/packages will pull in new imports added in overlay files when go/packages +is run in LoadImports mode or greater. +Overlay support for the go list driver isn't complete yet: if the file doesn't +exist on disk, it will only be recognized in an overlay if it is a non-test file +and the package would be reported even without the overlay. + +Questions & Tasks + +- Add GOARCH/GOOS? + They are not portable concepts, but could be made portable. + Our goal has been to allow users to express themselves using the conventions + of the underlying build system: if the build system honors GOARCH + during a build and during a metadata query, then so should + applications built atop that query mechanism. + Conversely, if the target architecture of the build is determined by + command-line flags, the application can pass the relevant + flags through to the build system using a command such as: + myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" + However, this approach is low-level, unwieldy, and non-portable. + GOOS and GOARCH seem important enough to warrant a dedicated option. + +- How should we handle partial failures such as a mixture of good and + malformed patterns, existing and non-existent packages, successful and + failed builds, import failures, import cycles, and so on, in a call to + Load? + +- Support bazel, blaze, and go1.10 list, not just go1.11 list. + +- Handle (and test) various partial success cases, e.g. + a mixture of good packages and: + invalid patterns + nonexistent packages + empty packages + packages with malformed package or import declarations + unreadable files + import cycles + other parse errors + type errors + Make sure we record errors at the correct place in the graph. + +- Missing packages among initial arguments are not reported. + Return bogus packages for them, like golist does. + +- "undeclared name" errors (for example) are reported out of source file + order. I suspect this is due to the breadth-first resolution now used + by go/types. Is that a bug? Discuss with gri. + +*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go new file mode 100644 index 0000000..8c8473f --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/external.go @@ -0,0 +1,101 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file enables an external tool to intercept package requests. +// If the tool is present then its results are used in preference to +// the go list command. + +package packages + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "strings" +) + +// The Driver Protocol +// +// The driver, given the inputs to a call to Load, returns metadata about the packages specified. +// This allows for different build systems to support go/packages by telling go/packages how the +// packages' source is organized. +// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in +// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package +// documentation in doc.go for the full description of the patterns that need to be supported. +// A driver receives as a JSON-serialized driverRequest struct in standard input and will +// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. + +// driverRequest is used to provide the portion of Load's Config that is needed by a driver. +type driverRequest struct { + Mode LoadMode `json:"mode"` + // Env specifies the environment the underlying build system should be run in. + Env []string `json:"env"` + // BuildFlags are flags that should be passed to the underlying build system. + BuildFlags []string `json:"build_flags"` + // Tests specifies whether the patterns should also return test packages. + Tests bool `json:"tests"` + // Overlay maps file paths (relative to the driver's working directory) to the byte contents + // of overlay files. + Overlay map[string][]byte `json:"overlay"` +} + +// findExternalDriver returns the file path of a tool that supplies +// the build system package structure, or "" if not found." +// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its +// value, otherwise it searches for a binary named gopackagesdriver on the PATH. +func findExternalDriver(cfg *Config) driver { + const toolPrefix = "GOPACKAGESDRIVER=" + tool := "" + for _, env := range cfg.Env { + if val := strings.TrimPrefix(env, toolPrefix); val != env { + tool = val + } + } + if tool != "" && tool == "off" { + return nil + } + if tool == "" { + var err error + tool, err = exec.LookPath("gopackagesdriver") + if err != nil { + return nil + } + } + return func(cfg *Config, words ...string) (*driverResponse, error) { + req, err := json.Marshal(driverRequest{ + Mode: cfg.Mode, + Env: cfg.Env, + BuildFlags: cfg.BuildFlags, + Tests: cfg.Tests, + Overlay: cfg.Overlay, + }) + if err != nil { + return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) + } + + buf := new(bytes.Buffer) + stderr := new(bytes.Buffer) + cmd := exec.CommandContext(cfg.Context, tool, words...) + cmd.Dir = cfg.Dir + cmd.Env = cfg.Env + cmd.Stdin = bytes.NewReader(req) + cmd.Stdout = buf + cmd.Stderr = stderr + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) + } + if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { + fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr) + } + + var response driverResponse + if err := json.Unmarshal(buf.Bytes(), &response); err != nil { + return nil, err + } + return &response, nil + } +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go new file mode 100644 index 0000000..b4d232b --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -0,0 +1,996 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "go/types" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "unicode" + + "golang.org/x/tools/go/internal/packagesdriver" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/xerrors" +) + +// debug controls verbose logging. +var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) + +// A goTooOldError reports that the go command +// found by exec.LookPath is too old to use the new go list behavior. +type goTooOldError struct { + error +} + +// responseDeduper wraps a driverResponse, deduplicating its contents. +type responseDeduper struct { + seenRoots map[string]bool + seenPackages map[string]*Package + dr *driverResponse +} + +func newDeduper() *responseDeduper { + return &responseDeduper{ + dr: &driverResponse{}, + seenRoots: map[string]bool{}, + seenPackages: map[string]*Package{}, + } +} + +// addAll fills in r with a driverResponse. +func (r *responseDeduper) addAll(dr *driverResponse) { + for _, pkg := range dr.Packages { + r.addPackage(pkg) + } + for _, root := range dr.Roots { + r.addRoot(root) + } +} + +func (r *responseDeduper) addPackage(p *Package) { + if r.seenPackages[p.ID] != nil { + return + } + r.seenPackages[p.ID] = p + r.dr.Packages = append(r.dr.Packages, p) +} + +func (r *responseDeduper) addRoot(id string) { + if r.seenRoots[id] { + return + } + r.seenRoots[id] = true + r.dr.Roots = append(r.dr.Roots, id) +} + +type golistState struct { + cfg *Config + ctx context.Context + + envOnce sync.Once + goEnvError error + goEnv map[string]string + + rootsOnce sync.Once + rootDirsError error + rootDirs map[string]string + + goVersionOnce sync.Once + goVersionError error + goVersion string // third field of 'go version' + + // vendorDirs caches the (non)existence of vendor directories. + vendorDirs map[string]bool +} + +// getEnv returns Go environment variables. Only specific variables are +// populated -- computing all of them is slow. +func (state *golistState) getEnv() (map[string]string, error) { + state.envOnce.Do(func() { + var b *bytes.Buffer + b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") + if state.goEnvError != nil { + return + } + + state.goEnv = make(map[string]string) + decoder := json.NewDecoder(b) + if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { + return + } + }) + return state.goEnv, state.goEnvError +} + +// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. +func (state *golistState) mustGetEnv() map[string]string { + env, err := state.getEnv() + if err != nil { + panic(fmt.Sprintf("mustGetEnv: %v", err)) + } + return env +} + +// goListDriver uses the go list command to interpret the patterns and produce +// the build system package structure. +// See driver for more details. +func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) { + // Make sure that any asynchronous go commands are killed when we return. + parentCtx := cfg.Context + if parentCtx == nil { + parentCtx = context.Background() + } + ctx, cancel := context.WithCancel(parentCtx) + defer cancel() + + response := newDeduper() + + // Fill in response.Sizes asynchronously if necessary. + var sizeserr error + var sizeswg sync.WaitGroup + if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 { + sizeswg.Add(1) + go func() { + var sizes types.Sizes + sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.gocmdRunner, cfg.Dir) + // types.SizesFor always returns nil or a *types.StdSizes. + response.dr.Sizes, _ = sizes.(*types.StdSizes) + sizeswg.Done() + }() + } + + state := &golistState{ + cfg: cfg, + ctx: ctx, + vendorDirs: map[string]bool{}, + } + + // Determine files requested in contains patterns + var containFiles []string + restPatterns := make([]string, 0, len(patterns)) + // Extract file= and other [querytype]= patterns. Report an error if querytype + // doesn't exist. +extractQueries: + for _, pattern := range patterns { + eqidx := strings.Index(pattern, "=") + if eqidx < 0 { + restPatterns = append(restPatterns, pattern) + } else { + query, value := pattern[:eqidx], pattern[eqidx+len("="):] + switch query { + case "file": + containFiles = append(containFiles, value) + case "pattern": + restPatterns = append(restPatterns, value) + case "": // not a reserved query + restPatterns = append(restPatterns, pattern) + default: + for _, rune := range query { + if rune < 'a' || rune > 'z' { // not a reserved query + restPatterns = append(restPatterns, pattern) + continue extractQueries + } + } + // Reject all other patterns containing "=" + return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) + } + } + } + + // See if we have any patterns to pass through to go list. Zero initial + // patterns also requires a go list call, since it's the equivalent of + // ".". + if len(restPatterns) > 0 || len(patterns) == 0 { + dr, err := state.createDriverResponse(restPatterns...) + if err != nil { + return nil, err + } + response.addAll(dr) + } + + if len(containFiles) != 0 { + if err := state.runContainsQueries(response, containFiles); err != nil { + return nil, err + } + } + + modifiedPkgs, needPkgs, err := state.processGolistOverlay(response) + if err != nil { + return nil, err + } + + var containsCandidates []string + if len(containFiles) > 0 { + containsCandidates = append(containsCandidates, modifiedPkgs...) + containsCandidates = append(containsCandidates, needPkgs...) + } + if err := state.addNeededOverlayPackages(response, needPkgs); err != nil { + return nil, err + } + // Check candidate packages for containFiles. + if len(containFiles) > 0 { + for _, id := range containsCandidates { + pkg, ok := response.seenPackages[id] + if !ok { + response.addPackage(&Package{ + ID: id, + Errors: []Error{ + { + Kind: ListError, + Msg: fmt.Sprintf("package %s expected but not seen", id), + }, + }, + }) + continue + } + for _, f := range containFiles { + for _, g := range pkg.GoFiles { + if sameFile(f, g) { + response.addRoot(id) + } + } + } + } + } + + sizeswg.Wait() + if sizeserr != nil { + return nil, sizeserr + } + return response.dr, nil +} + +func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error { + if len(pkgs) == 0 { + return nil + } + dr, err := state.createDriverResponse(pkgs...) + if err != nil { + return err + } + for _, pkg := range dr.Packages { + response.addPackage(pkg) + } + _, needPkgs, err := state.processGolistOverlay(response) + if err != nil { + return err + } + return state.addNeededOverlayPackages(response, needPkgs) +} + +func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { + for _, query := range queries { + // TODO(matloob): Do only one query per directory. + fdir := filepath.Dir(query) + // Pass absolute path of directory to go list so that it knows to treat it as a directory, + // not a package path. + pattern, err := filepath.Abs(fdir) + if err != nil { + return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) + } + dirResponse, err := state.createDriverResponse(pattern) + + // If there was an error loading the package, or the package is returned + // with errors, try to load the file as an ad-hoc package. + // Usually the error will appear in a returned package, but may not if we're + // in module mode and the ad-hoc is located outside a module. + if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + len(dirResponse.Packages[0].Errors) == 1 { + var queryErr error + if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { + return err // return the original error + } + } + isRoot := make(map[string]bool, len(dirResponse.Roots)) + for _, root := range dirResponse.Roots { + isRoot[root] = true + } + for _, pkg := range dirResponse.Packages { + // Add any new packages to the main set + // We don't bother to filter packages that will be dropped by the changes of roots, + // that will happen anyway during graph construction outside this function. + // Over-reporting packages is not a problem. + response.addPackage(pkg) + // if the package was not a root one, it cannot have the file + if !isRoot[pkg.ID] { + continue + } + for _, pkgFile := range pkg.GoFiles { + if filepath.Base(query) == filepath.Base(pkgFile) { + response.addRoot(pkg.ID) + break + } + } + } + } + return nil +} + +// adhocPackage attempts to load or construct an ad-hoc package for a given +// query, if the original call to the driver produced inadequate results. +func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) { + response, err := state.createDriverResponse(query) + if err != nil { + return nil, err + } + // If we get nothing back from `go list`, + // try to make this file into its own ad-hoc package. + // TODO(rstambler): Should this check against the original response? + if len(response.Packages) == 0 { + response.Packages = append(response.Packages, &Package{ + ID: "command-line-arguments", + PkgPath: query, + GoFiles: []string{query}, + CompiledGoFiles: []string{query}, + Imports: make(map[string]*Package), + }) + response.Roots = append(response.Roots, "command-line-arguments") + } + // Handle special cases. + if len(response.Packages) == 1 { + // golang/go#33482: If this is a file= query for ad-hoc packages where + // the file only exists on an overlay, and exists outside of a module, + // add the file to the package and remove the errors. + if response.Packages[0].ID == "command-line-arguments" || + filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { + if len(response.Packages[0].GoFiles) == 0 { + filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath + // TODO(matloob): check if the file is outside of a root dir? + for path := range state.cfg.Overlay { + if path == filename { + response.Packages[0].Errors = nil + response.Packages[0].GoFiles = []string{path} + response.Packages[0].CompiledGoFiles = []string{path} + } + } + } + } + } + return response, nil +} + +// Fields must match go list; +// see $GOROOT/src/cmd/go/internal/load/pkg.go. +type jsonPackage struct { + ImportPath string + Dir string + Name string + Export string + GoFiles []string + CompiledGoFiles []string + CFiles []string + CgoFiles []string + CXXFiles []string + MFiles []string + HFiles []string + FFiles []string + SFiles []string + SwigFiles []string + SwigCXXFiles []string + SysoFiles []string + Imports []string + ImportMap map[string]string + Deps []string + Module *Module + TestGoFiles []string + TestImports []string + XTestGoFiles []string + XTestImports []string + ForTest string // q in a "p [q.test]" package, else "" + DepOnly bool + + Error *jsonPackageError +} + +type jsonPackageError struct { + ImportStack []string + Pos string + Err string +} + +func otherFiles(p *jsonPackage) [][]string { + return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} +} + +// createDriverResponse uses the "go list" command to expand the pattern +// words and return a response for the specified packages. +func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) { + // go list uses the following identifiers in ImportPath and Imports: + // + // "p" -- importable package or main (command) + // "q.test" -- q's test executable + // "p [q.test]" -- variant of p as built for q's test executable + // "q_test [q.test]" -- q's external test package + // + // The packages p that are built differently for a test q.test + // are q itself, plus any helpers used by the external test q_test, + // typically including "testing" and all its dependencies. + + // Run "go list" for complete + // information on the specified packages. + buf, err := state.invokeGo("list", golistargs(state.cfg, words)...) + if err != nil { + return nil, err + } + seen := make(map[string]*jsonPackage) + pkgs := make(map[string]*Package) + additionalErrors := make(map[string][]Error) + // Decode the JSON and convert it to Package form. + var response driverResponse + for dec := json.NewDecoder(buf); dec.More(); { + p := new(jsonPackage) + if err := dec.Decode(p); err != nil { + return nil, fmt.Errorf("JSON decoding failed: %v", err) + } + + if p.ImportPath == "" { + // The documentation for go list says that “[e]rroneous packages will have + // a non-empty ImportPath”. If for some reason it comes back empty, we + // prefer to error out rather than silently discarding data or handing + // back a package without any way to refer to it. + if p.Error != nil { + return nil, Error{ + Pos: p.Error.Pos, + Msg: p.Error.Err, + } + } + return nil, fmt.Errorf("package missing import path: %+v", p) + } + + // Work around https://golang.org/issue/33157: + // go list -e, when given an absolute path, will find the package contained at + // that directory. But when no package exists there, it will return a fake package + // with an error and the ImportPath set to the absolute path provided to go list. + // Try to convert that absolute path to what its package path would be if it's + // contained in a known module or GOPATH entry. This will allow the package to be + // properly "reclaimed" when overlays are processed. + if filepath.IsAbs(p.ImportPath) && p.Error != nil { + pkgPath, ok, err := state.getPkgPath(p.ImportPath) + if err != nil { + return nil, err + } + if ok { + p.ImportPath = pkgPath + } + } + + if old, found := seen[p.ImportPath]; found { + // If one version of the package has an error, and the other doesn't, assume + // that this is a case where go list is reporting a fake dependency variant + // of the imported package: When a package tries to invalidly import another + // package, go list emits a variant of the imported package (with the same + // import path, but with an error on it, and the package will have a + // DepError set on it). An example of when this can happen is for imports of + // main packages: main packages can not be imported, but they may be + // separately matched and listed by another pattern. + // See golang.org/issue/36188 for more details. + + // The plan is that eventually, hopefully in Go 1.15, the error will be + // reported on the importing package rather than the duplicate "fake" + // version of the imported package. Once all supported versions of Go + // have the new behavior this logic can be deleted. + // TODO(matloob): delete the workaround logic once all supported versions of + // Go return the errors on the proper package. + + // There should be exactly one version of a package that doesn't have an + // error. + if old.Error == nil && p.Error == nil { + if !reflect.DeepEqual(p, old) { + return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) + } + continue + } + + // Determine if this package's error needs to be bubbled up. + // This is a hack, and we expect for go list to eventually set the error + // on the package. + if old.Error != nil { + var errkind string + if strings.Contains(old.Error.Err, "not an importable package") { + errkind = "not an importable package" + } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { + errkind = "use of internal package not allowed" + } + if errkind != "" { + if len(old.Error.ImportStack) < 1 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) + } + importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] + if importingPkg == old.ImportPath { + // Using an older version of Go which put this package itself on top of import + // stack, instead of the importer. Look for importer in second from top + // position. + if len(old.Error.ImportStack) < 2 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) + } + importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] + } + additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ + Pos: old.Error.Pos, + Msg: old.Error.Err, + Kind: ListError, + }) + } + } + + // Make sure that if there's a version of the package without an error, + // that's the one reported to the user. + if old.Error == nil { + continue + } + + // This package will replace the old one at the end of the loop. + } + seen[p.ImportPath] = p + + pkg := &Package{ + Name: p.Name, + ID: p.ImportPath, + GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), + CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), + OtherFiles: absJoin(p.Dir, otherFiles(p)...), + forTest: p.ForTest, + Module: p.Module, + } + + if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { + if len(p.CompiledGoFiles) > len(p.GoFiles) { + // We need the cgo definitions, which are in the first + // CompiledGoFile after the non-cgo ones. This is a hack but there + // isn't currently a better way to find it. We also need the pure + // Go files and unprocessed cgo files, all of which are already + // in pkg.GoFiles. + cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] + pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) + } else { + // golang/go#38990: go list silently fails to do cgo processing + pkg.CompiledGoFiles = nil + pkg.Errors = append(pkg.Errors, Error{ + Msg: "go list failed to return CompiledGoFiles; https://golang.org/issue/38990?", + Kind: ListError, + }) + } + } + + // Work around https://golang.org/issue/28749: + // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. + // Filter out any elements of CompiledGoFiles that are also in OtherFiles. + // We have to keep this workaround in place until go1.12 is a distant memory. + if len(pkg.OtherFiles) > 0 { + other := make(map[string]bool, len(pkg.OtherFiles)) + for _, f := range pkg.OtherFiles { + other[f] = true + } + + out := pkg.CompiledGoFiles[:0] + for _, f := range pkg.CompiledGoFiles { + if other[f] { + continue + } + out = append(out, f) + } + pkg.CompiledGoFiles = out + } + + // Extract the PkgPath from the package's ID. + if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { + pkg.PkgPath = pkg.ID[:i] + } else { + pkg.PkgPath = pkg.ID + } + + if pkg.PkgPath == "unsafe" { + pkg.GoFiles = nil // ignore fake unsafe.go file + } + + // Assume go list emits only absolute paths for Dir. + if p.Dir != "" && !filepath.IsAbs(p.Dir) { + log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) + } + + if p.Export != "" && !filepath.IsAbs(p.Export) { + pkg.ExportFile = filepath.Join(p.Dir, p.Export) + } else { + pkg.ExportFile = p.Export + } + + // imports + // + // Imports contains the IDs of all imported packages. + // ImportsMap records (path, ID) only where they differ. + ids := make(map[string]bool) + for _, id := range p.Imports { + ids[id] = true + } + pkg.Imports = make(map[string]*Package) + for path, id := range p.ImportMap { + pkg.Imports[path] = &Package{ID: id} // non-identity import + delete(ids, id) + } + for id := range ids { + if id == "C" { + continue + } + + pkg.Imports[id] = &Package{ID: id} // identity import + } + if !p.DepOnly { + response.Roots = append(response.Roots, pkg.ID) + } + + // Work around for pre-go.1.11 versions of go list. + // TODO(matloob): they should be handled by the fallback. + // Can we delete this? + if len(pkg.CompiledGoFiles) == 0 { + pkg.CompiledGoFiles = pkg.GoFiles + } + + // Temporary work-around for golang/go#39986. Parse filenames out of + // error messages. This happens if there are unrecoverable syntax + // errors in the source, so we can't match on a specific error message. + if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { + addFilenameFromPos := func(pos string) bool { + split := strings.Split(pos, ":") + if len(split) < 1 { + return false + } + filename := strings.TrimSpace(split[0]) + if filename == "" { + return false + } + if !filepath.IsAbs(filename) { + filename = filepath.Join(state.cfg.Dir, filename) + } + info, _ := os.Stat(filename) + if info == nil { + return false + } + pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) + pkg.GoFiles = append(pkg.GoFiles, filename) + return true + } + found := addFilenameFromPos(err.Pos) + // In some cases, go list only reports the error position in the + // error text, not the error position. One such case is when the + // file's package name is a keyword (see golang.org/issue/39763). + if !found { + addFilenameFromPos(err.Err) + } + } + + if p.Error != nil { + msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. + // Address golang.org/issue/35964 by appending import stack to error message. + if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { + msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) + } + pkg.Errors = append(pkg.Errors, Error{ + Pos: p.Error.Pos, + Msg: msg, + Kind: ListError, + }) + } + + pkgs[pkg.ID] = pkg + } + + for id, errs := range additionalErrors { + if p, ok := pkgs[id]; ok { + p.Errors = append(p.Errors, errs...) + } + } + for _, pkg := range pkgs { + response.Packages = append(response.Packages, pkg) + } + sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) + + return &response, nil +} + +func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { + if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { + return false + } + + goV, err := state.getGoVersion() + if err != nil { + return false + } + + // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. + // The import stack behaves differently for these versions than newer Go versions. + if strings.HasPrefix(goV, "go1.13") || strings.HasPrefix(goV, "go1.14") { + return len(p.Error.ImportStack) == 0 + } + + // On Go 1.15 and later, only parse filenames out of error if there's no import stack, + // or the current package is at the top of the import stack. This is not guaranteed + // to work perfectly, but should avoid some cases where files in errors don't belong to this + // package. + return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath +} + +func (state *golistState) getGoVersion() (string, error) { + state.goVersionOnce.Do(func() { + var b *bytes.Buffer + // Invoke go version. Don't use invokeGo because it will supply build flags, and + // go version doesn't expect build flags. + inv := gocommand.Invocation{ + Verb: "version", + Env: state.cfg.Env, + Logf: state.cfg.Logf, + } + gocmdRunner := state.cfg.gocmdRunner + if gocmdRunner == nil { + gocmdRunner = &gocommand.Runner{} + } + b, _, _, state.goVersionError = gocmdRunner.RunRaw(state.cfg.Context, inv) + if state.goVersionError != nil { + return + } + + sp := strings.Split(b.String(), " ") + if len(sp) < 3 { + state.goVersionError = fmt.Errorf("go version output: expected 'go version ', got '%s'", b.String()) + return + } + state.goVersion = sp[2] + }) + return state.goVersion, state.goVersionError +} + +// getPkgPath finds the package path of a directory if it's relative to a root directory. +func (state *golistState) getPkgPath(dir string) (string, bool, error) { + absDir, err := filepath.Abs(dir) + if err != nil { + return "", false, err + } + roots, err := state.determineRootDirs() + if err != nil { + return "", false, err + } + + for rdir, rpath := range roots { + // Make sure that the directory is in the module, + // to avoid creating a path relative to another module. + if !strings.HasPrefix(absDir, rdir) { + continue + } + // TODO(matloob): This doesn't properly handle symlinks. + r, err := filepath.Rel(rdir, dir) + if err != nil { + continue + } + if rpath != "" { + // We choose only one root even though the directory even it can belong in multiple modules + // or GOPATH entries. This is okay because we only need to work with absolute dirs when a + // file is missing from disk, for instance when gopls calls go/packages in an overlay. + // Once the file is saved, gopls, or the next invocation of the tool will get the correct + // result straight from golist. + // TODO(matloob): Implement module tiebreaking? + return path.Join(rpath, filepath.ToSlash(r)), true, nil + } + return filepath.ToSlash(r), true, nil + } + return "", false, nil +} + +// absJoin absolutizes and flattens the lists of files. +func absJoin(dir string, fileses ...[]string) (res []string) { + for _, files := range fileses { + for _, file := range files { + if !filepath.IsAbs(file) { + file = filepath.Join(dir, file) + } + res = append(res, file) + } + } + return res +} + +func golistargs(cfg *Config, words []string) []string { + const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo + fullargs := []string{ + "-e", "-json", + fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), + fmt.Sprintf("-test=%t", cfg.Tests), + fmt.Sprintf("-export=%t", usesExportData(cfg)), + fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), + // go list doesn't let you pass -test and -find together, + // probably because you'd just get the TestMain. + fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0), + } + fullargs = append(fullargs, cfg.BuildFlags...) + fullargs = append(fullargs, "--") + fullargs = append(fullargs, words...) + return fullargs +} + +// invokeGo returns the stdout of a go command invocation. +func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { + cfg := state.cfg + + inv := gocommand.Invocation{ + Verb: verb, + Args: args, + BuildFlags: cfg.BuildFlags, + Env: cfg.Env, + Logf: cfg.Logf, + WorkingDir: cfg.Dir, + } + gocmdRunner := cfg.gocmdRunner + if gocmdRunner == nil { + gocmdRunner = &gocommand.Runner{} + } + stdout, stderr, _, err := gocmdRunner.RunRaw(cfg.Context, inv) + if err != nil { + // Check for 'go' executable not being found. + if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) + } + + exitErr, ok := err.(*exec.ExitError) + if !ok { + // Catastrophic error: + // - context cancellation + return nil, xerrors.Errorf("couldn't run 'go': %w", err) + } + + // Old go version? + if strings.Contains(stderr.String(), "flag provided but not defined") { + return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} + } + + // Related to #24854 + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { + return nil, fmt.Errorf("%s", stderr.String()) + } + + // Is there an error running the C compiler in cgo? This will be reported in the "Error" field + // and should be suppressed by go list -e. + // + // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. + isPkgPathRune := func(r rune) bool { + // From https://golang.org/ref/spec#Import_declarations: + // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings + // using only characters belonging to Unicode's L, M, N, P, and S general categories + // (the Graphic characters without spaces) and may also exclude the + // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. + return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && + !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) + } + if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { + msg := stderr.String()[len("# "):] + if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { + return stdout, nil + } + // Treat pkg-config errors as a special case (golang.org/issue/36770). + if strings.HasPrefix(msg, "pkg-config") { + return stdout, nil + } + } + + // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show + // the error in the Err section of stdout in case -e option is provided. + // This fix is provided for backwards compatibility. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Similar to the previous error, but currently lacks a fix in Go. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. + // If the package doesn't exist, put the absolute path of the directory into the error message, + // as Go 1.13 list does. + const noSuchDirectory = "no such directory" + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { + errstr := stderr.String() + abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + abspath, strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. + // Note that the error message we look for in this case is different that the one looked for above. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a + // directory outside any module. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Another variation of the previous error + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit + // status if there's a dependency on a package that doesn't exist. But it should return + // a zero exit status and set an error on that package. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { + // Don't clobber stdout if `go list` actually returned something. + if len(stdout.String()) > 0 { + return stdout, nil + } + // try to extract package name from string + stderrStr := stderr.String() + var importPath string + colon := strings.Index(stderrStr, ":") + if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { + importPath = stderrStr[len("go build "):colon] + } + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + importPath, strings.Trim(stderrStr, "\n")) + return bytes.NewBufferString(output), nil + } + + // Export mode entails a build. + // If that build fails, errors appear on stderr + // (despite the -e flag) and the Export field is blank. + // Do not fail in that case. + // The same is true if an ad-hoc package given to go list doesn't exist. + // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when + // packages don't exist or a build fails. + if !usesExportData(cfg) && !containsGoFile(args) { + return nil, fmt.Errorf("go %v: %s: %s", args, exitErr, stderr) + } + } + return stdout, nil +} + +func containsGoFile(s []string) bool { + for _, f := range s { + if strings.HasSuffix(f, ".go") { + return true + } + } + return false +} + +func cmdDebugStr(cmd *exec.Cmd, args ...string) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.Split(kv, "=") + k, v := split[0], split[1] + env[k] = v + } + var quotedArgs []string + for _, arg := range args { + quotedArgs = append(quotedArgs, strconv.Quote(arg)) + } + + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v PWD=%v go %s", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["PWD"], strings.Join(quotedArgs, " ")) +} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go new file mode 100644 index 0000000..4eabfd9 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go @@ -0,0 +1,473 @@ +package packages + +import ( + "encoding/json" + "fmt" + "go/parser" + "go/token" + "log" + "os" + "path/filepath" + "sort" + "strconv" + "strings" +) + +// processGolistOverlay provides rudimentary support for adding +// files that don't exist on disk to an overlay. The results can be +// sometimes incorrect. +// TODO(matloob): Handle unsupported cases, including the following: +// - determining the correct package to add given a new import path +func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) { + havePkgs := make(map[string]string) // importPath -> non-test package ID + needPkgsSet := make(map[string]bool) + modifiedPkgsSet := make(map[string]bool) + + pkgOfDir := make(map[string][]*Package) + for _, pkg := range response.dr.Packages { + // This is an approximation of import path to id. This can be + // wrong for tests, vendored packages, and a number of other cases. + havePkgs[pkg.PkgPath] = pkg.ID + x := commonDir(pkg.GoFiles) + if x != "" { + pkgOfDir[x] = append(pkgOfDir[x], pkg) + } + } + + // If no new imports are added, it is safe to avoid loading any needPkgs. + // Otherwise, it's hard to tell which package is actually being loaded + // (due to vendoring) and whether any modified package will show up + // in the transitive set of dependencies (because new imports are added, + // potentially modifying the transitive set of dependencies). + var overlayAddsImports bool + + // If both a package and its test package are created by the overlay, we + // need the real package first. Process all non-test files before test + // files, and make the whole process deterministic while we're at it. + var overlayFiles []string + for opath := range state.cfg.Overlay { + overlayFiles = append(overlayFiles, opath) + } + sort.Slice(overlayFiles, func(i, j int) bool { + iTest := strings.HasSuffix(overlayFiles[i], "_test.go") + jTest := strings.HasSuffix(overlayFiles[j], "_test.go") + if iTest != jTest { + return !iTest // non-tests are before tests. + } + return overlayFiles[i] < overlayFiles[j] + }) + for _, opath := range overlayFiles { + contents := state.cfg.Overlay[opath] + base := filepath.Base(opath) + dir := filepath.Dir(opath) + var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant + var testVariantOf *Package // if opath is a test file, this is the package it is testing + var fileExists bool + isTestFile := strings.HasSuffix(opath, "_test.go") + pkgName, ok := extractPackageName(opath, contents) + if !ok { + // Don't bother adding a file that doesn't even have a parsable package statement + // to the overlay. + continue + } + // If all the overlay files belong to a different package, change the + // package name to that package. + maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir]) + nextPackage: + for _, p := range response.dr.Packages { + if pkgName != p.Name && p.ID != "command-line-arguments" { + continue + } + for _, f := range p.GoFiles { + if !sameFile(filepath.Dir(f), dir) { + continue + } + // Make sure to capture information on the package's test variant, if needed. + if isTestFile && !hasTestFiles(p) { + // TODO(matloob): Are there packages other than the 'production' variant + // of a package that this can match? This shouldn't match the test main package + // because the file is generated in another directory. + testVariantOf = p + continue nextPackage + } + // We must have already seen the package of which this is a test variant. + if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath { + if hasTestFiles(p) { + testVariantOf = pkg + } + } + pkg = p + if filepath.Base(f) == base { + fileExists = true + } + } + } + // The overlay could have included an entirely new package or an + // ad-hoc package. An ad-hoc package is one that we have manually + // constructed from inadequate `go list` results for a file= query. + // It will have the ID command-line-arguments. + if pkg == nil || pkg.ID == "command-line-arguments" { + // Try to find the module or gopath dir the file is contained in. + // Then for modules, add the module opath to the beginning. + pkgPath, ok, err := state.getPkgPath(dir) + if err != nil { + return nil, nil, err + } + if !ok { + break + } + var forTest string // only set for x tests + isXTest := strings.HasSuffix(pkgName, "_test") + if isXTest { + forTest = pkgPath + pkgPath += "_test" + } + id := pkgPath + if isTestFile { + if isXTest { + id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest) + } else { + id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath) + } + } + if pkg != nil { + // TODO(rstambler): We should change the package's path and ID + // here. The only issue is that this messes with the roots. + } else { + // Try to reclaim a package with the same ID, if it exists in the response. + for _, p := range response.dr.Packages { + if reclaimPackage(p, id, opath, contents) { + pkg = p + break + } + } + // Otherwise, create a new package. + if pkg == nil { + pkg = &Package{ + PkgPath: pkgPath, + ID: id, + Name: pkgName, + Imports: make(map[string]*Package), + } + response.addPackage(pkg) + havePkgs[pkg.PkgPath] = id + // Add the production package's sources for a test variant. + if isTestFile && !isXTest && testVariantOf != nil { + pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...) + pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...) + // Add the package under test and its imports to the test variant. + pkg.forTest = testVariantOf.PkgPath + for k, v := range testVariantOf.Imports { + pkg.Imports[k] = &Package{ID: v.ID} + } + } + if isXTest { + pkg.forTest = forTest + } + } + } + } + if !fileExists { + pkg.GoFiles = append(pkg.GoFiles, opath) + // TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior + // if the file will be ignored due to its build tags. + pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath) + modifiedPkgsSet[pkg.ID] = true + } + imports, err := extractImports(opath, contents) + if err != nil { + // Let the parser or type checker report errors later. + continue + } + for _, imp := range imports { + // TODO(rstambler): If the package is an x test and the import has + // a test variant, make sure to replace it. + if _, found := pkg.Imports[imp]; found { + continue + } + overlayAddsImports = true + id, ok := havePkgs[imp] + if !ok { + var err error + id, err = state.resolveImport(dir, imp) + if err != nil { + return nil, nil, err + } + } + pkg.Imports[imp] = &Package{ID: id} + // Add dependencies to the non-test variant version of this package as well. + if testVariantOf != nil { + testVariantOf.Imports[imp] = &Package{ID: id} + } + } + } + + // toPkgPath guesses the package path given the id. + toPkgPath := func(sourceDir, id string) (string, error) { + if i := strings.IndexByte(id, ' '); i >= 0 { + return state.resolveImport(sourceDir, id[:i]) + } + return state.resolveImport(sourceDir, id) + } + + // Now that new packages have been created, do another pass to determine + // the new set of missing packages. + for _, pkg := range response.dr.Packages { + for _, imp := range pkg.Imports { + if len(pkg.GoFiles) == 0 { + return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath) + } + pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID) + if err != nil { + return nil, nil, err + } + if _, ok := havePkgs[pkgPath]; !ok { + needPkgsSet[pkgPath] = true + } + } + } + + if overlayAddsImports { + needPkgs = make([]string, 0, len(needPkgsSet)) + for pkg := range needPkgsSet { + needPkgs = append(needPkgs, pkg) + } + } + modifiedPkgs = make([]string, 0, len(modifiedPkgsSet)) + for pkg := range modifiedPkgsSet { + modifiedPkgs = append(modifiedPkgs, pkg) + } + return modifiedPkgs, needPkgs, err +} + +// resolveImport finds the the ID of a package given its import path. +// In particular, it will find the right vendored copy when in GOPATH mode. +func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) { + env, err := state.getEnv() + if err != nil { + return "", err + } + if env["GOMOD"] != "" { + return importPath, nil + } + + searchDir := sourceDir + for { + vendorDir := filepath.Join(searchDir, "vendor") + exists, ok := state.vendorDirs[vendorDir] + if !ok { + info, err := os.Stat(vendorDir) + exists = err == nil && info.IsDir() + state.vendorDirs[vendorDir] = exists + } + + if exists { + vendoredPath := filepath.Join(vendorDir, importPath) + if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() { + // We should probably check for .go files here, but shame on anyone who fools us. + path, ok, err := state.getPkgPath(vendoredPath) + if err != nil { + return "", err + } + if ok { + return path, nil + } + } + } + + // We know we've hit the top of the filesystem when we Dir / and get /, + // or C:\ and get C:\, etc. + next := filepath.Dir(searchDir) + if next == searchDir { + break + } + searchDir = next + } + return importPath, nil +} + +func hasTestFiles(p *Package) bool { + for _, f := range p.GoFiles { + if strings.HasSuffix(f, "_test.go") { + return true + } + } + return false +} + +// determineRootDirs returns a mapping from absolute directories that could +// contain code to their corresponding import path prefixes. +func (state *golistState) determineRootDirs() (map[string]string, error) { + env, err := state.getEnv() + if err != nil { + return nil, err + } + if env["GOMOD"] != "" { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsModules() + }) + } else { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() + }) + } + return state.rootDirs, state.rootDirsError +} + +func (state *golistState) determineRootDirsModules() (map[string]string, error) { + // This will only return the root directory for the main module. + // For now we only support overlays in main modules. + // Editing files in the module cache isn't a great idea, so we don't + // plan to ever support that, but editing files in replaced modules + // is something we may want to support. To do that, we'll want to + // do a go list -m to determine the replaced module's module path and + // directory, and then a go list -m {{with .Replace}}{{.Dir}}{{end}} + // from the main module to determine if that module is actually a replacement. + // See bcmills's comment here: https://github.com/golang/go/issues/37629#issuecomment-594179751 + // for more information. + out, err := state.invokeGo("list", "-m", "-json") + if err != nil { + return nil, err + } + m := map[string]string{} + type jsonMod struct{ Path, Dir string } + for dec := json.NewDecoder(out); dec.More(); { + mod := new(jsonMod) + if err := dec.Decode(mod); err != nil { + return nil, err + } + if mod.Dir != "" && mod.Path != "" { + // This is a valid module; add it to the map. + absDir, err := filepath.Abs(mod.Dir) + if err != nil { + return nil, err + } + m[absDir] = mod.Path + } + } + return m, nil +} + +func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { + m := map[string]string{} + for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { + absDir, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + m[filepath.Join(absDir, "src")] = "" + } + return m, nil +} + +func extractImports(filename string, contents []byte) ([]string, error) { + f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset? + if err != nil { + return nil, err + } + var res []string + for _, imp := range f.Imports { + quotedPath := imp.Path.Value + path, err := strconv.Unquote(quotedPath) + if err != nil { + return nil, err + } + res = append(res, path) + } + return res, nil +} + +// reclaimPackage attempts to reuse a package that failed to load in an overlay. +// +// If the package has errors and has no Name, GoFiles, or Imports, +// then it's possible that it doesn't yet exist on disk. +func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool { + // TODO(rstambler): Check the message of the actual error? + // It differs between $GOPATH and module mode. + if pkg.ID != id { + return false + } + if len(pkg.Errors) != 1 { + return false + } + if pkg.Name != "" || pkg.ExportFile != "" { + return false + } + if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 { + return false + } + if len(pkg.Imports) > 0 { + return false + } + pkgName, ok := extractPackageName(filename, contents) + if !ok { + return false + } + pkg.Name = pkgName + pkg.Errors = nil + return true +} + +func extractPackageName(filename string, contents []byte) (string, bool) { + // TODO(rstambler): Check the message of the actual error? + // It differs between $GOPATH and module mode. + f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset? + if err != nil { + return "", false + } + return f.Name.Name, true +} + +func commonDir(a []string) string { + seen := make(map[string]bool) + x := append([]string{}, a...) + for _, f := range x { + seen[filepath.Dir(f)] = true + } + if len(seen) > 1 { + log.Fatalf("commonDir saw %v for %v", seen, x) + } + for k := range seen { + // len(seen) == 1 + return k + } + return "" // no files +} + +// It is possible that the files in the disk directory dir have a different package +// name from newName, which is deduced from the overlays. If they all have a different +// package name, and they all have the same package name, then that name becomes +// the package name. +// It returns true if it changes the package name, false otherwise. +func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) { + names := make(map[string]int) + for _, p := range pkgsOfDir { + names[p.Name]++ + } + if len(names) != 1 { + // some files are in different packages + return + } + var oldName string + for k := range names { + oldName = k + } + if newName == oldName { + return + } + // We might have a case where all of the package names in the directory are + // the same, but the overlay file is for an x test, which belongs to its + // own package. If the x test does not yet exist on disk, we may not yet + // have its package name on disk, but we should not rename the packages. + // + // We use a heuristic to determine if this file belongs to an x test: + // The test file should have a package name whose package name has a _test + // suffix or looks like "newName_test". + maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test") + if isTestFile && maybeXTest { + return + } + for _, p := range pkgsOfDir { + p.Name = newName + } +} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go new file mode 100644 index 0000000..7ea37e7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go @@ -0,0 +1,57 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "fmt" + "strings" +) + +var allModes = []LoadMode{ + NeedName, + NeedFiles, + NeedCompiledGoFiles, + NeedImports, + NeedDeps, + NeedExportsFile, + NeedTypes, + NeedSyntax, + NeedTypesInfo, + NeedTypesSizes, +} + +var modeStrings = []string{ + "NeedName", + "NeedFiles", + "NeedCompiledGoFiles", + "NeedImports", + "NeedDeps", + "NeedExportsFile", + "NeedTypes", + "NeedSyntax", + "NeedTypesInfo", + "NeedTypesSizes", +} + +func (mod LoadMode) String() string { + m := mod + if m == 0 { + return "LoadMode(0)" + } + var out []string + for i, x := range allModes { + if x > m { + break + } + if (m & x) != 0 { + out = append(out, modeStrings[i]) + m = m ^ x + } + } + if m != 0 { + out = append(out, "Unknown") + } + return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|")) +} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go new file mode 100644 index 0000000..04053f1 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -0,0 +1,1212 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +// See doc.go for package documentation and implementation notes. + +import ( + "context" + "encoding/json" + "fmt" + "go/ast" + "go/parser" + "go/scanner" + "go/token" + "go/types" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + "sync" + "time" + + "golang.org/x/tools/go/gcexportdata" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/packagesinternal" + "golang.org/x/tools/internal/typesinternal" +) + +// A LoadMode controls the amount of detail to return when loading. +// The bits below can be combined to specify which fields should be +// filled in the result packages. +// The zero value is a special case, equivalent to combining +// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. +// ID and Errors (if present) will always be filled. +// Load may return more information than requested. +type LoadMode int + +// TODO(matloob): When a V2 of go/packages is released, rename NeedExportsFile to +// NeedExportFile to make it consistent with the Package field it's adding. + +const ( + // NeedName adds Name and PkgPath. + NeedName LoadMode = 1 << iota + + // NeedFiles adds GoFiles and OtherFiles. + NeedFiles + + // NeedCompiledGoFiles adds CompiledGoFiles. + NeedCompiledGoFiles + + // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain + // "placeholder" Packages with only the ID set. + NeedImports + + // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. + NeedDeps + + // NeedExportsFile adds ExportFile. + NeedExportsFile + + // NeedTypes adds Types, Fset, and IllTyped. + NeedTypes + + // NeedSyntax adds Syntax. + NeedSyntax + + // NeedTypesInfo adds TypesInfo. + NeedTypesInfo + + // NeedTypesSizes adds TypesSizes. + NeedTypesSizes + + // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. + // Modifies CompiledGoFiles and Types, and has no effect on its own. + typecheckCgo + + // NeedModule adds Module. + NeedModule +) + +const ( + // Deprecated: LoadFiles exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles + + // Deprecated: LoadImports exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadImports = LoadFiles | NeedImports + + // Deprecated: LoadTypes exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadTypes = LoadImports | NeedTypes | NeedTypesSizes + + // Deprecated: LoadSyntax exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo + + // Deprecated: LoadAllSyntax exists for historical compatibility + // and should not be used. Please directly specify the needed fields using the Need values. + LoadAllSyntax = LoadSyntax | NeedDeps +) + +// A Config specifies details about how packages should be loaded. +// The zero value is a valid configuration. +// Calls to Load do not modify this struct. +type Config struct { + // Mode controls the level of information returned for each package. + Mode LoadMode + + // Context specifies the context for the load operation. + // If the context is cancelled, the loader may stop early + // and return an ErrCancelled error. + // If Context is nil, the load cannot be cancelled. + Context context.Context + + // Logf is the logger for the config. + // If the user provides a logger, debug logging is enabled. + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the logger is nil, default to log.Printf. + Logf func(format string, args ...interface{}) + + // Dir is the directory in which to run the build system's query tool + // that provides information about the packages. + // If Dir is empty, the tool is run in the current directory. + Dir string + + // Env is the environment to use when invoking the build system's query tool. + // If Env is nil, the current environment is used. + // As in os/exec's Cmd, only the last value in the slice for + // each environment key is used. To specify the setting of only + // a few variables, append to the current environment, as in: + // + // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") + // + Env []string + + // gocmdRunner guards go command calls from concurrency errors. + gocmdRunner *gocommand.Runner + + // BuildFlags is a list of command-line flags to be passed through to + // the build system's query tool. + BuildFlags []string + + // Fset provides source position information for syntax trees and types. + // If Fset is nil, Load will use a new fileset, but preserve Fset's value. + Fset *token.FileSet + + // ParseFile is called to read and parse each file + // when preparing a package's type-checked syntax tree. + // It must be safe to call ParseFile simultaneously from multiple goroutines. + // If ParseFile is nil, the loader will uses parser.ParseFile. + // + // ParseFile should parse the source from src and use filename only for + // recording position information. + // + // An application may supply a custom implementation of ParseFile + // to change the effective file contents or the behavior of the parser, + // or to modify the syntax tree. For example, selectively eliminating + // unwanted function bodies can significantly accelerate type checking. + ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) + + // If Tests is set, the loader includes not just the packages + // matching a particular pattern but also any related test packages, + // including test-only variants of the package and the test executable. + // + // For example, when using the go command, loading "fmt" with Tests=true + // returns four packages, with IDs "fmt" (the standard package), + // "fmt [fmt.test]" (the package as compiled for the test), + // "fmt_test" (the test functions from source files in package fmt_test), + // and "fmt.test" (the test binary). + // + // In build systems with explicit names for tests, + // setting Tests may have no effect. + Tests bool + + // Overlay provides a mapping of absolute file paths to file contents. + // If the file with the given path already exists, the parser will use the + // alternative file contents provided by the map. + // + // Overlays provide incomplete support for when a given file doesn't + // already exist on disk. See the package doc above for more details. + Overlay map[string][]byte +} + +// driver is the type for functions that query the build system for the +// packages named by the patterns. +type driver func(cfg *Config, patterns ...string) (*driverResponse, error) + +// driverResponse contains the results for a driver query. +type driverResponse struct { + // NotHandled is returned if the request can't be handled by the current + // driver. If an external driver returns a response with NotHandled, the + // rest of the driverResponse is ignored, and go/packages will fallback + // to the next driver. If go/packages is extended in the future to support + // lists of multiple drivers, go/packages will fall back to the next driver. + NotHandled bool + + // Sizes, if not nil, is the types.Sizes to use when type checking. + Sizes *types.StdSizes + + // Roots is the set of package IDs that make up the root packages. + // We have to encode this separately because when we encode a single package + // we cannot know if it is one of the roots as that requires knowledge of the + // graph it is part of. + Roots []string `json:",omitempty"` + + // Packages is the full set of packages in the graph. + // The packages are not connected into a graph. + // The Imports if populated will be stubs that only have their ID set. + // Imports will be connected and then type and syntax information added in a + // later pass (see refine). + Packages []*Package +} + +// Load loads and returns the Go packages named by the given patterns. +// +// Config specifies loading options; +// nil behaves the same as an empty Config. +// +// Load returns an error if any of the patterns was invalid +// as defined by the underlying build system. +// It may return an empty list of packages without an error, +// for instance for an empty expansion of a valid wildcard. +// Errors associated with a particular package are recorded in the +// corresponding Package's Errors list, and do not cause Load to +// return an error. Clients may need to handle such errors before +// proceeding with further analysis. The PrintErrors function is +// provided for convenient display of all errors. +func Load(cfg *Config, patterns ...string) ([]*Package, error) { + l := newLoader(cfg) + response, err := defaultDriver(&l.Config, patterns...) + if err != nil { + return nil, err + } + l.sizes = response.Sizes + return l.refine(response.Roots, response.Packages...) +} + +// defaultDriver is a driver that implements go/packages' fallback behavior. +// It will try to request to an external driver, if one exists. If there's +// no external driver, or the driver returns a response with NotHandled set, +// defaultDriver will fall back to the go list driver. +func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) { + driver := findExternalDriver(cfg) + if driver == nil { + driver = goListDriver + } + response, err := driver(cfg, patterns...) + if err != nil { + return response, err + } else if response.NotHandled { + return goListDriver(cfg, patterns...) + } + return response, nil +} + +// A Package describes a loaded Go package. +type Package struct { + // ID is a unique identifier for a package, + // in a syntax provided by the underlying build system. + // + // Because the syntax varies based on the build system, + // clients should treat IDs as opaque and not attempt to + // interpret them. + ID string + + // Name is the package name as it appears in the package source code. + Name string + + // PkgPath is the package path as used by the go/types package. + PkgPath string + + // Errors contains any errors encountered querying the metadata + // of the package, or while parsing or type-checking its files. + Errors []Error + + // GoFiles lists the absolute file paths of the package's Go source files. + GoFiles []string + + // CompiledGoFiles lists the absolute file paths of the package's source + // files that are suitable for type checking. + // This may differ from GoFiles if files are processed before compilation. + CompiledGoFiles []string + + // OtherFiles lists the absolute file paths of the package's non-Go source files, + // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. + OtherFiles []string + + // ExportFile is the absolute path to a file containing type + // information for the package as provided by the build system. + ExportFile string + + // Imports maps import paths appearing in the package's Go source files + // to corresponding loaded Packages. + Imports map[string]*Package + + // Types provides type information for the package. + // The NeedTypes LoadMode bit sets this field for packages matching the + // patterns; type information for dependencies may be missing or incomplete, + // unless NeedDeps and NeedImports are also set. + Types *types.Package + + // Fset provides position information for Types, TypesInfo, and Syntax. + // It is set only when Types is set. + Fset *token.FileSet + + // IllTyped indicates whether the package or any dependency contains errors. + // It is set only when Types is set. + IllTyped bool + + // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. + // + // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. + // If NeedDeps and NeedImports are also set, this field will also be populated + // for dependencies. + Syntax []*ast.File + + // TypesInfo provides type information about the package's syntax trees. + // It is set only when Syntax is set. + TypesInfo *types.Info + + // TypesSizes provides the effective size function for types in TypesInfo. + TypesSizes types.Sizes + + // forTest is the package under test, if any. + forTest string + + // module is the module information for the package if it exists. + Module *Module +} + +// Module provides module information for a package. +type Module struct { + Path string // module path + Version string // module version + Replace *Module // replaced by this module + Time *time.Time // time version was created + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module + Error *ModuleError // error loading module +} + +// ModuleError holds errors loading a module. +type ModuleError struct { + Err string // the error itself +} + +func init() { + packagesinternal.GetForTest = func(p interface{}) string { + return p.(*Package).forTest + } + packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner { + return config.(*Config).gocmdRunner + } + packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) { + config.(*Config).gocmdRunner = runner + } + packagesinternal.TypecheckCgo = int(typecheckCgo) +} + +// An Error describes a problem with a package's metadata, syntax, or types. +type Error struct { + Pos string // "file:line:col" or "file:line" or "" or "-" + Msg string + Kind ErrorKind +} + +// ErrorKind describes the source of the error, allowing the user to +// differentiate between errors generated by the driver, the parser, or the +// type-checker. +type ErrorKind int + +const ( + UnknownError ErrorKind = iota + ListError + ParseError + TypeError +) + +func (err Error) Error() string { + pos := err.Pos + if pos == "" { + pos = "-" // like token.Position{}.String() + } + return pos + ": " + err.Msg +} + +// flatPackage is the JSON form of Package +// It drops all the type and syntax fields, and transforms the Imports +// +// TODO(adonovan): identify this struct with Package, effectively +// publishing the JSON protocol. +type flatPackage struct { + ID string + Name string `json:",omitempty"` + PkgPath string `json:",omitempty"` + Errors []Error `json:",omitempty"` + GoFiles []string `json:",omitempty"` + CompiledGoFiles []string `json:",omitempty"` + OtherFiles []string `json:",omitempty"` + ExportFile string `json:",omitempty"` + Imports map[string]string `json:",omitempty"` +} + +// MarshalJSON returns the Package in its JSON form. +// For the most part, the structure fields are written out unmodified, and +// the type and syntax fields are skipped. +// The imports are written out as just a map of path to package id. +// The errors are written using a custom type that tries to preserve the +// structure of error types we know about. +// +// This method exists to enable support for additional build systems. It is +// not intended for use by clients of the API and we may change the format. +func (p *Package) MarshalJSON() ([]byte, error) { + flat := &flatPackage{ + ID: p.ID, + Name: p.Name, + PkgPath: p.PkgPath, + Errors: p.Errors, + GoFiles: p.GoFiles, + CompiledGoFiles: p.CompiledGoFiles, + OtherFiles: p.OtherFiles, + ExportFile: p.ExportFile, + } + if len(p.Imports) > 0 { + flat.Imports = make(map[string]string, len(p.Imports)) + for path, ipkg := range p.Imports { + flat.Imports[path] = ipkg.ID + } + } + return json.Marshal(flat) +} + +// UnmarshalJSON reads in a Package from its JSON format. +// See MarshalJSON for details about the format accepted. +func (p *Package) UnmarshalJSON(b []byte) error { + flat := &flatPackage{} + if err := json.Unmarshal(b, &flat); err != nil { + return err + } + *p = Package{ + ID: flat.ID, + Name: flat.Name, + PkgPath: flat.PkgPath, + Errors: flat.Errors, + GoFiles: flat.GoFiles, + CompiledGoFiles: flat.CompiledGoFiles, + OtherFiles: flat.OtherFiles, + ExportFile: flat.ExportFile, + } + if len(flat.Imports) > 0 { + p.Imports = make(map[string]*Package, len(flat.Imports)) + for path, id := range flat.Imports { + p.Imports[path] = &Package{ID: id} + } + } + return nil +} + +func (p *Package) String() string { return p.ID } + +// loaderPackage augments Package with state used during the loading phase +type loaderPackage struct { + *Package + importErrors map[string]error // maps each bad import to its error + loadOnce sync.Once + color uint8 // for cycle detection + needsrc bool // load from source (Mode >= LoadTypes) + needtypes bool // type information is either requested or depended on + initial bool // package was matched by a pattern +} + +// loader holds the working state of a single call to load. +type loader struct { + pkgs map[string]*loaderPackage + Config + sizes types.Sizes + parseCache map[string]*parseValue + parseCacheMu sync.Mutex + exportMu sync.Mutex // enforces mutual exclusion of exportdata operations + + // Config.Mode contains the implied mode (see impliedLoadMode). + // Implied mode contains all the fields we need the data for. + // In requestedMode there are the actually requested fields. + // We'll zero them out before returning packages to the user. + // This makes it easier for us to get the conditions where + // we need certain modes right. + requestedMode LoadMode +} + +type parseValue struct { + f *ast.File + err error + ready chan struct{} +} + +func newLoader(cfg *Config) *loader { + ld := &loader{ + parseCache: map[string]*parseValue{}, + } + if cfg != nil { + ld.Config = *cfg + // If the user has provided a logger, use it. + ld.Config.Logf = cfg.Logf + } + if ld.Config.Logf == nil { + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the user has not provided a logger, default to log.Printf. + if debug { + ld.Config.Logf = log.Printf + } else { + ld.Config.Logf = func(format string, args ...interface{}) {} + } + } + if ld.Config.Mode == 0 { + ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. + } + if ld.Config.Env == nil { + ld.Config.Env = os.Environ() + } + if ld.Config.gocmdRunner == nil { + ld.Config.gocmdRunner = &gocommand.Runner{} + } + if ld.Context == nil { + ld.Context = context.Background() + } + if ld.Dir == "" { + if dir, err := os.Getwd(); err == nil { + ld.Dir = dir + } + } + + // Save the actually requested fields. We'll zero them out before returning packages to the user. + ld.requestedMode = ld.Mode + ld.Mode = impliedLoadMode(ld.Mode) + + if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { + if ld.Fset == nil { + ld.Fset = token.NewFileSet() + } + + // ParseFile is required even in LoadTypes mode + // because we load source if export data is missing. + if ld.ParseFile == nil { + ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { + const mode = parser.AllErrors | parser.ParseComments + return parser.ParseFile(fset, filename, src, mode) + } + } + } + + return ld +} + +// refine connects the supplied packages into a graph and then adds type and +// and syntax information as requested by the LoadMode. +func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { + rootMap := make(map[string]int, len(roots)) + for i, root := range roots { + rootMap[root] = i + } + ld.pkgs = make(map[string]*loaderPackage) + // first pass, fixup and build the map and roots + var initial = make([]*loaderPackage, len(roots)) + for _, pkg := range list { + rootIndex := -1 + if i, found := rootMap[pkg.ID]; found { + rootIndex = i + } + + // Overlays can invalidate export data. + // TODO(matloob): make this check fine-grained based on dependencies on overlaid files + exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" + // This package needs type information if the caller requested types and the package is + // either a root, or it's a non-root and the user requested dependencies ... + needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) + // This package needs source if the call requested source (or types info, which implies source) + // and the package is either a root, or itas a non- root and the user requested dependencies... + needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || + // ... or if we need types and the exportData is invalid. We fall back to (incompletely) + // typechecking packages from source if they fail to compile. + (ld.Mode&NeedTypes|NeedTypesInfo != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" + lpkg := &loaderPackage{ + Package: pkg, + needtypes: needtypes, + needsrc: needsrc, + } + ld.pkgs[lpkg.ID] = lpkg + if rootIndex >= 0 { + initial[rootIndex] = lpkg + lpkg.initial = true + } + } + for i, root := range roots { + if initial[i] == nil { + return nil, fmt.Errorf("root package %v is missing", root) + } + } + + // Materialize the import graph. + + const ( + white = 0 // new + grey = 1 // in progress + black = 2 // complete + ) + + // visit traverses the import graph, depth-first, + // and materializes the graph as Packages.Imports. + // + // Valid imports are saved in the Packages.Import map. + // Invalid imports (cycles and missing nodes) are saved in the importErrors map. + // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG. + // + // visit returns whether the package needs src or has a transitive + // dependency on a package that does. These are the only packages + // for which we load source code. + var stack []*loaderPackage + var visit func(lpkg *loaderPackage) bool + var srcPkgs []*loaderPackage + visit = func(lpkg *loaderPackage) bool { + switch lpkg.color { + case black: + return lpkg.needsrc + case grey: + panic("internal error: grey node") + } + lpkg.color = grey + stack = append(stack, lpkg) // push + stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports + // If NeedImports isn't set, the imports fields will all be zeroed out. + if ld.Mode&NeedImports != 0 { + lpkg.Imports = make(map[string]*Package, len(stubs)) + for importPath, ipkg := range stubs { + var importErr error + imp := ld.pkgs[ipkg.ID] + if imp == nil { + // (includes package "C" when DisableCgo) + importErr = fmt.Errorf("missing package: %q", ipkg.ID) + } else if imp.color == grey { + importErr = fmt.Errorf("import cycle: %s", stack) + } + if importErr != nil { + if lpkg.importErrors == nil { + lpkg.importErrors = make(map[string]error) + } + lpkg.importErrors[importPath] = importErr + continue + } + + if visit(imp) { + lpkg.needsrc = true + } + lpkg.Imports[importPath] = imp.Package + } + } + if lpkg.needsrc { + srcPkgs = append(srcPkgs, lpkg) + } + if ld.Mode&NeedTypesSizes != 0 { + lpkg.TypesSizes = ld.sizes + } + stack = stack[:len(stack)-1] // pop + lpkg.color = black + + return lpkg.needsrc + } + + if ld.Mode&NeedImports == 0 { + // We do this to drop the stub import packages that we are not even going to try to resolve. + for _, lpkg := range initial { + lpkg.Imports = nil + } + } else { + // For each initial package, create its import DAG. + for _, lpkg := range initial { + visit(lpkg) + } + } + if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 { + for _, lpkg := range srcPkgs { + // Complete type information is required for the + // immediate dependencies of each source package. + for _, ipkg := range lpkg.Imports { + imp := ld.pkgs[ipkg.ID] + imp.needtypes = true + } + } + } + // Load type data and syntax if needed, starting at + // the initial packages (roots of the import DAG). + if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { + var wg sync.WaitGroup + for _, lpkg := range initial { + wg.Add(1) + go func(lpkg *loaderPackage) { + ld.loadRecursive(lpkg) + wg.Done() + }(lpkg) + } + wg.Wait() + } + + result := make([]*Package, len(initial)) + for i, lpkg := range initial { + result[i] = lpkg.Package + } + for i := range ld.pkgs { + // Clear all unrequested fields, for extra de-Hyrum-ization. + if ld.requestedMode&NeedName == 0 { + ld.pkgs[i].Name = "" + ld.pkgs[i].PkgPath = "" + } + if ld.requestedMode&NeedFiles == 0 { + ld.pkgs[i].GoFiles = nil + ld.pkgs[i].OtherFiles = nil + } + if ld.requestedMode&NeedCompiledGoFiles == 0 { + ld.pkgs[i].CompiledGoFiles = nil + } + if ld.requestedMode&NeedImports == 0 { + ld.pkgs[i].Imports = nil + } + if ld.requestedMode&NeedExportsFile == 0 { + ld.pkgs[i].ExportFile = "" + } + if ld.requestedMode&NeedTypes == 0 { + ld.pkgs[i].Types = nil + ld.pkgs[i].Fset = nil + ld.pkgs[i].IllTyped = false + } + if ld.requestedMode&NeedSyntax == 0 { + ld.pkgs[i].Syntax = nil + } + if ld.requestedMode&NeedTypesInfo == 0 { + ld.pkgs[i].TypesInfo = nil + } + if ld.requestedMode&NeedTypesSizes == 0 { + ld.pkgs[i].TypesSizes = nil + } + if ld.requestedMode&NeedModule == 0 { + ld.pkgs[i].Module = nil + } + } + + return result, nil +} + +// loadRecursive loads the specified package and its dependencies, +// recursively, in parallel, in topological order. +// It is atomic and idempotent. +// Precondition: ld.Mode&NeedTypes. +func (ld *loader) loadRecursive(lpkg *loaderPackage) { + lpkg.loadOnce.Do(func() { + // Load the direct dependencies, in parallel. + var wg sync.WaitGroup + for _, ipkg := range lpkg.Imports { + imp := ld.pkgs[ipkg.ID] + wg.Add(1) + go func(imp *loaderPackage) { + ld.loadRecursive(imp) + wg.Done() + }(imp) + } + wg.Wait() + ld.loadPackage(lpkg) + }) +} + +// loadPackage loads the specified package. +// It must be called only once per Package, +// after immediate dependencies are loaded. +// Precondition: ld.Mode & NeedTypes. +func (ld *loader) loadPackage(lpkg *loaderPackage) { + if lpkg.PkgPath == "unsafe" { + // Fill in the blanks to avoid surprises. + lpkg.Types = types.Unsafe + lpkg.Fset = ld.Fset + lpkg.Syntax = []*ast.File{} + lpkg.TypesInfo = new(types.Info) + lpkg.TypesSizes = ld.sizes + return + } + + // Call NewPackage directly with explicit name. + // This avoids skew between golist and go/types when the files' + // package declarations are inconsistent. + lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) + lpkg.Fset = ld.Fset + + // Subtle: we populate all Types fields with an empty Package + // before loading export data so that export data processing + // never has to create a types.Package for an indirect dependency, + // which would then require that such created packages be explicitly + // inserted back into the Import graph as a final step after export data loading. + // The Diamond test exercises this case. + if !lpkg.needtypes && !lpkg.needsrc { + return + } + if !lpkg.needsrc { + ld.loadFromExportData(lpkg) + return // not a source package, don't get syntax trees + } + + appendError := func(err error) { + // Convert various error types into the one true Error. + var errs []Error + switch err := err.(type) { + case Error: + // from driver + errs = append(errs, err) + + case *os.PathError: + // from parser + errs = append(errs, Error{ + Pos: err.Path + ":1", + Msg: err.Err.Error(), + Kind: ParseError, + }) + + case scanner.ErrorList: + // from parser + for _, err := range err { + errs = append(errs, Error{ + Pos: err.Pos.String(), + Msg: err.Msg, + Kind: ParseError, + }) + } + + case types.Error: + // from type checker + errs = append(errs, Error{ + Pos: err.Fset.Position(err.Pos).String(), + Msg: err.Msg, + Kind: TypeError, + }) + + default: + // unexpected impoverished error from parser? + errs = append(errs, Error{ + Pos: "-", + Msg: err.Error(), + Kind: UnknownError, + }) + + // If you see this error message, please file a bug. + log.Printf("internal error: error %q (%T) without position", err, err) + } + + lpkg.Errors = append(lpkg.Errors, errs...) + } + + if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { + // The config requested loading sources and types, but sources are missing. + // Add an error to the package and fall back to loading from export data. + appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) + ld.loadFromExportData(lpkg) + return // can't get syntax trees for this package + } + + files, errs := ld.parseFiles(lpkg.CompiledGoFiles) + for _, err := range errs { + appendError(err) + } + + lpkg.Syntax = files + if ld.Config.Mode&NeedTypes == 0 { + return + } + + lpkg.TypesInfo = &types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + } + lpkg.TypesSizes = ld.sizes + + importer := importerFunc(func(path string) (*types.Package, error) { + if path == "unsafe" { + return types.Unsafe, nil + } + + // The imports map is keyed by import path. + ipkg := lpkg.Imports[path] + if ipkg == nil { + if err := lpkg.importErrors[path]; err != nil { + return nil, err + } + // There was skew between the metadata and the + // import declarations, likely due to an edit + // race, or because the ParseFile feature was + // used to supply alternative file contents. + return nil, fmt.Errorf("no metadata for %s", path) + } + + if ipkg.Types != nil && ipkg.Types.Complete() { + return ipkg.Types, nil + } + log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) + panic("unreachable") + }) + + // type-check + tc := &types.Config{ + Importer: importer, + + // Type-check bodies of functions only in non-initial packages. + // Example: for import graph A->B->C and initial packages {A,C}, + // we can ignore function bodies in B. + IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, + + Error: appendError, + Sizes: ld.sizes, + } + if (ld.Mode & typecheckCgo) != 0 { + if !typesinternal.SetUsesCgo(tc) { + appendError(Error{ + Msg: "typecheckCgo requires Go 1.15+", + Kind: ListError, + }) + return + } + } + types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) + + lpkg.importErrors = nil // no longer needed + + // If !Cgo, the type-checker uses FakeImportC mode, so + // it doesn't invoke the importer for import "C", + // nor report an error for the import, + // or for any undefined C.f reference. + // We must detect this explicitly and correctly + // mark the package as IllTyped (by reporting an error). + // TODO(adonovan): if these errors are annoying, + // we could just set IllTyped quietly. + if tc.FakeImportC { + outer: + for _, f := range lpkg.Syntax { + for _, imp := range f.Imports { + if imp.Path.Value == `"C"` { + err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} + appendError(err) + break outer + } + } + } + } + + // Record accumulated errors. + illTyped := len(lpkg.Errors) > 0 + if !illTyped { + for _, imp := range lpkg.Imports { + if imp.IllTyped { + illTyped = true + break + } + } + } + lpkg.IllTyped = illTyped +} + +// An importFunc is an implementation of the single-method +// types.Importer interface based on a function value. +type importerFunc func(path string) (*types.Package, error) + +func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } + +// We use a counting semaphore to limit +// the number of parallel I/O calls per process. +var ioLimit = make(chan bool, 20) + +func (ld *loader) parseFile(filename string) (*ast.File, error) { + ld.parseCacheMu.Lock() + v, ok := ld.parseCache[filename] + if ok { + // cache hit + ld.parseCacheMu.Unlock() + <-v.ready + } else { + // cache miss + v = &parseValue{ready: make(chan struct{})} + ld.parseCache[filename] = v + ld.parseCacheMu.Unlock() + + var src []byte + for f, contents := range ld.Config.Overlay { + if sameFile(f, filename) { + src = contents + } + } + var err error + if src == nil { + ioLimit <- true // wait + src, err = ioutil.ReadFile(filename) + <-ioLimit // signal + } + if err != nil { + v.err = err + } else { + v.f, v.err = ld.ParseFile(ld.Fset, filename, src) + } + + close(v.ready) + } + return v.f, v.err +} + +// parseFiles reads and parses the Go source files and returns the ASTs +// of the ones that could be at least partially parsed, along with a +// list of I/O and parse errors encountered. +// +// Because files are scanned in parallel, the token.Pos +// positions of the resulting ast.Files are not ordered. +// +func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { + var wg sync.WaitGroup + n := len(filenames) + parsed := make([]*ast.File, n) + errors := make([]error, n) + for i, file := range filenames { + if ld.Config.Context.Err() != nil { + parsed[i] = nil + errors[i] = ld.Config.Context.Err() + continue + } + wg.Add(1) + go func(i int, filename string) { + parsed[i], errors[i] = ld.parseFile(filename) + wg.Done() + }(i, file) + } + wg.Wait() + + // Eliminate nils, preserving order. + var o int + for _, f := range parsed { + if f != nil { + parsed[o] = f + o++ + } + } + parsed = parsed[:o] + + o = 0 + for _, err := range errors { + if err != nil { + errors[o] = err + o++ + } + } + errors = errors[:o] + + return parsed, errors +} + +// sameFile returns true if x and y have the same basename and denote +// the same file. +// +func sameFile(x, y string) bool { + if x == y { + // It could be the case that y doesn't exist. + // For instance, it may be an overlay file that + // hasn't been written to disk. To handle that case + // let x == y through. (We added the exact absolute path + // string to the CompiledGoFiles list, so the unwritten + // overlay case implies x==y.) + return true + } + if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) + if xi, err := os.Stat(x); err == nil { + if yi, err := os.Stat(y); err == nil { + return os.SameFile(xi, yi) + } + } + } + return false +} + +// loadFromExportData returns type information for the specified +// package, loading it from an export data file on the first request. +func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) { + if lpkg.PkgPath == "" { + log.Fatalf("internal error: Package %s has no PkgPath", lpkg) + } + + // Because gcexportdata.Read has the potential to create or + // modify the types.Package for each node in the transitive + // closure of dependencies of lpkg, all exportdata operations + // must be sequential. (Finer-grained locking would require + // changes to the gcexportdata API.) + // + // The exportMu lock guards the Package.Pkg field and the + // types.Package it points to, for each Package in the graph. + // + // Not all accesses to Package.Pkg need to be protected by exportMu: + // graph ordering ensures that direct dependencies of source + // packages are fully loaded before the importer reads their Pkg field. + ld.exportMu.Lock() + defer ld.exportMu.Unlock() + + if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { + return tpkg, nil // cache hit + } + + lpkg.IllTyped = true // fail safe + + if lpkg.ExportFile == "" { + // Errors while building export data will have been printed to stderr. + return nil, fmt.Errorf("no export data file") + } + f, err := os.Open(lpkg.ExportFile) + if err != nil { + return nil, err + } + defer f.Close() + + // Read gc export data. + // + // We don't currently support gccgo export data because all + // underlying workspaces use the gc toolchain. (Even build + // systems that support gccgo don't use it for workspace + // queries.) + r, err := gcexportdata.NewReader(f) + if err != nil { + return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + + // Build the view. + // + // The gcexportdata machinery has no concept of package ID. + // It identifies packages by their PkgPath, which although not + // globally unique is unique within the scope of one invocation + // of the linker, type-checker, or gcexportdata. + // + // So, we must build a PkgPath-keyed view of the global + // (conceptually ID-keyed) cache of packages and pass it to + // gcexportdata. The view must contain every existing + // package that might possibly be mentioned by the + // current package---its transitive closure. + // + // In loadPackage, we unconditionally create a types.Package for + // each dependency so that export data loading does not + // create new ones. + // + // TODO(adonovan): it would be simpler and more efficient + // if the export data machinery invoked a callback to + // get-or-create a package instead of a map. + // + view := make(map[string]*types.Package) // view seen by gcexportdata + seen := make(map[*loaderPackage]bool) // all visited packages + var visit func(pkgs map[string]*Package) + visit = func(pkgs map[string]*Package) { + for _, p := range pkgs { + lpkg := ld.pkgs[p.ID] + if !seen[lpkg] { + seen[lpkg] = true + view[lpkg.PkgPath] = lpkg.Types + visit(lpkg.Imports) + } + } + } + visit(lpkg.Imports) + + viewLen := len(view) + 1 // adding the self package + // Parse the export data. + // (May modify incomplete packages in view but not create new ones.) + tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) + if err != nil { + return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + if viewLen != len(view) { + log.Fatalf("Unexpected package creation during export data loading") + } + + lpkg.Types = tpkg + lpkg.IllTyped = false + + return tpkg, nil +} + +// impliedLoadMode returns loadMode with its dependencies. +func impliedLoadMode(loadMode LoadMode) LoadMode { + if loadMode&NeedTypesInfo != 0 && loadMode&NeedImports == 0 { + // If NeedTypesInfo, go/packages needs to do typechecking itself so it can + // associate type info with the AST. To do so, we need the export data + // for dependencies, which means we need to ask for the direct dependencies. + // NeedImports is used to ask for the direct dependencies. + loadMode |= NeedImports + } + + if loadMode&NeedDeps != 0 && loadMode&NeedImports == 0 { + // With NeedDeps we need to load at least direct dependencies. + // NeedImports is used to ask for the direct dependencies. + loadMode |= NeedImports + } + + return loadMode +} + +func usesExportData(cfg *Config) bool { + return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 +} diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go new file mode 100644 index 0000000..b13cb08 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -0,0 +1,55 @@ +package packages + +import ( + "fmt" + "os" + "sort" +) + +// Visit visits all the packages in the import graph whose roots are +// pkgs, calling the optional pre function the first time each package +// is encountered (preorder), and the optional post function after a +// package's dependencies have been visited (postorder). +// The boolean result of pre(pkg) determines whether +// the imports of package pkg are visited. +func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { + seen := make(map[*Package]bool) + var visit func(*Package) + visit = func(pkg *Package) { + if !seen[pkg] { + seen[pkg] = true + + if pre == nil || pre(pkg) { + paths := make([]string, 0, len(pkg.Imports)) + for path := range pkg.Imports { + paths = append(paths, path) + } + sort.Strings(paths) // Imports is a map, this makes visit stable + for _, path := range paths { + visit(pkg.Imports[path]) + } + } + + if post != nil { + post(pkg) + } + } + } + for _, pkg := range pkgs { + visit(pkg) + } +} + +// PrintErrors prints to os.Stderr the accumulated errors of all +// packages in the import graph rooted at pkgs, dependencies first. +// PrintErrors returns the number of errors printed. +func PrintErrors(pkgs []*Package) int { + var n int + Visit(pkgs, nil, func(pkg *Package) { + for _, err := range pkg.Errors { + fmt.Fprintln(os.Stderr, err) + n++ + } + }) + return n +} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go new file mode 100644 index 0000000..e37b494 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -0,0 +1,85 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package core provides support for event based telemetry. +package core + +import ( + "fmt" + "time" + + "golang.org/x/tools/internal/event/label" +) + +// Event holds the information about an event of note that ocurred. +type Event struct { + at time.Time + + // As events are often on the stack, storing the first few labels directly + // in the event can avoid an allocation at all for the very common cases of + // simple events. + // The length needs to be large enough to cope with the majority of events + // but no so large as to cause undue stack pressure. + // A log message with two values will use 3 labels (one for each value and + // one for the message itself). + + static [3]label.Label // inline storage for the first few labels + dynamic []label.Label // dynamically sized storage for remaining labels +} + +// eventLabelMap implements label.Map for a the labels of an Event. +type eventLabelMap struct { + event Event +} + +func (ev Event) At() time.Time { return ev.at } + +func (ev Event) Format(f fmt.State, r rune) { + if !ev.at.IsZero() { + fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) + } + for index := 0; ev.Valid(index); index++ { + if l := ev.Label(index); l.Valid() { + fmt.Fprintf(f, "\n\t%v", l) + } + } +} + +func (ev Event) Valid(index int) bool { + return index >= 0 && index < len(ev.static)+len(ev.dynamic) +} + +func (ev Event) Label(index int) label.Label { + if index < len(ev.static) { + return ev.static[index] + } + return ev.dynamic[index-len(ev.static)] +} + +func (ev Event) Find(key label.Key) label.Label { + for _, l := range ev.static { + if l.Key() == key { + return l + } + } + for _, l := range ev.dynamic { + if l.Key() == key { + return l + } + } + return label.Label{} +} + +func MakeEvent(static [3]label.Label, labels []label.Label) Event { + return Event{ + static: static, + dynamic: labels, + } +} + +// CloneEvent event returns a copy of the event with the time adjusted to at. +func CloneEvent(ev Event, at time.Time) Event { + ev.at = at + return ev +} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go new file mode 100644 index 0000000..05f3a9a --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/export.go @@ -0,0 +1,70 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + "sync/atomic" + "time" + "unsafe" + + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, Event, label.Map) context.Context + +var ( + exporter unsafe.Pointer +) + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + p := unsafe.Pointer(&e) + if e == nil { + // &e is always valid, and so p is always valid, but for the early abort + // of ProcessEvent to be efficient it needs to make the nil check on the + // pointer without having to dereference it, so we make the nil function + // also a nil pointer + p = nil + } + atomic.StorePointer(&exporter, p) +} + +// deliver is called to deliver an event to the supplied exporter. +// it will fill in the time. +func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { + // add the current time to the event + ev.at = time.Now() + // hand the event off to the current exporter + return exporter(ctx, ev, ev) +} + +// Export is called to deliver an event to the global exporter if set. +func Export(ctx context.Context, ev Event) context.Context { + // get the global exporter and abort early if there is not one + exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + if exporterPtr == nil { + return ctx + } + return deliver(ctx, *exporterPtr, ev) +} + +// ExportPair is called to deliver a start event to the supplied exporter. +// It also returns a function that will deliver the end event to the same +// exporter. +// It will fill in the time. +func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { + // get the global exporter and abort early if there is not one + exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + if exporterPtr == nil { + return ctx, func() {} + } + ctx = deliver(ctx, *exporterPtr, begin) + return ctx, func() { deliver(ctx, *exporterPtr, end) } +} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go new file mode 100644 index 0000000..06c1d46 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/fast.go @@ -0,0 +1,77 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Log1 takes a message and one label delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log1(ctx context.Context, message string, t1 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + }, nil)) +} + +// Log2 takes a message and two labels and delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + t2, + }, nil)) +} + +// Metric1 sends a label event to the exporter with the supplied labels. +func Metric1(ctx context.Context, t1 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + }, nil)) +} + +// Metric2 sends a label event to the exporter with the supplied labels. +func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + t2, + }, nil)) +} + +// Start1 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// Start2 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + t2, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go new file mode 100644 index 0000000..5dc6e6b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/doc.go @@ -0,0 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package event provides a set of packages that cover the main +// concepts of telemetry in an implementation agnostic way. +package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go new file mode 100644 index 0000000..4d55e57 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/event.go @@ -0,0 +1,127 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package event + +import ( + "context" + + "golang.org/x/tools/internal/event/core" + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, core.Event, label.Map) context.Context + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + core.SetExporter(core.Exporter(e)) +} + +// Log takes a message and a label list and combines them into a single event +// before delivering them to the exporter. +func Log(ctx context.Context, message string, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + }, labels)) +} + +// IsLog returns true if the event was built by the Log function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLog(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg +} + +// Error takes a message and a label list and combines them into a single event +// before delivering them to the exporter. It captures the error in the +// delivered event. +func Error(ctx context.Context, message string, err error, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + keys.Err.Of(err), + }, labels)) +} + +// IsError returns true if the event was built by the Error function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsError(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg && + ev.Label(1).Key() == keys.Err +} + +// Metric sends a label event to the exporter with the supplied labels. +func Metric(ctx context.Context, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Metric.New(), + }, labels)) +} + +// IsMetric returns true if the event was built by the Metric function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsMetric(ev core.Event) bool { + return ev.Label(0).Key() == keys.Metric +} + +// Label sends a label event to the exporter with the supplied labels. +func Label(ctx context.Context, labels ...label.Label) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Label.New(), + }, labels)) +} + +// IsLabel returns true if the event was built by the Label function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLabel(ev core.Event) bool { + return ev.Label(0).Key() == keys.Label +} + +// Start sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { + return core.ExportPair(ctx, + core.MakeEvent([3]label.Label{ + keys.Start.Of(name), + }, labels), + core.MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// IsStart returns true if the event was built by the Start function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsStart(ev core.Event) bool { + return ev.Label(0).Key() == keys.Start +} + +// IsEnd returns true if the event was built by the End function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsEnd(ev core.Event) bool { + return ev.Label(0).Key() == keys.End +} + +// Detach returns a context without an associated span. +// This allows the creation of spans that are not children of the current span. +func Detach(ctx context.Context) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Detach.New(), + }, nil)) +} + +// IsDetach returns true if the event was built by the Detach function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsDetach(ev core.Event) bool { + return ev.Label(0).Key() == keys.Detach +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go new file mode 100644 index 0000000..a02206e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go @@ -0,0 +1,564 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +import ( + "fmt" + "io" + "math" + "strconv" + + "golang.org/x/tools/internal/event/label" +) + +// Value represents a key for untyped values. +type Value struct { + name string + description string +} + +// New creates a new Key for untyped values. +func New(name, description string) *Value { + return &Value{name: name, description: description} +} + +func (k *Value) Name() string { return k.name } +func (k *Value) Description() string { return k.description } + +func (k *Value) Format(w io.Writer, buf []byte, l label.Label) { + fmt.Fprint(w, k.From(l)) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Value) Get(lm label.Map) interface{} { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From can be used to get a value from a Label. +func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() } + +// Of creates a new Label with this key and the supplied value. +func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) } + +// Tag represents a key for tagging labels that have no value. +// These are used when the existence of the label is the entire information it +// carries, such as marking events to be of a specific kind, or from a specific +// package. +type Tag struct { + name string + description string +} + +// NewTag creates a new Key for tagging labels. +func NewTag(name, description string) *Tag { + return &Tag{name: name, description: description} +} + +func (k *Tag) Name() string { return k.name } +func (k *Tag) Description() string { return k.description } + +func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {} + +// New creates a new Label with this key. +func (k *Tag) New() label.Label { return label.OfValue(k, nil) } + +// Int represents a key +type Int struct { + name string + description string +} + +// NewInt creates a new Key for int values. +func NewInt(name, description string) *Int { + return &Int{name: name, description: description} +} + +func (k *Int) Name() string { return k.name } +func (k *Int) Description() string { return k.description } + +func (k *Int) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int) Get(lm label.Map) int { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int) From(t label.Label) int { return int(t.Unpack64()) } + +// Int8 represents a key +type Int8 struct { + name string + description string +} + +// NewInt8 creates a new Key for int8 values. +func NewInt8(name, description string) *Int8 { + return &Int8{name: name, description: description} +} + +func (k *Int8) Name() string { return k.name } +func (k *Int8) Description() string { return k.description } + +func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int8) Get(lm label.Map) int8 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) } + +// Int16 represents a key +type Int16 struct { + name string + description string +} + +// NewInt16 creates a new Key for int16 values. +func NewInt16(name, description string) *Int16 { + return &Int16{name: name, description: description} +} + +func (k *Int16) Name() string { return k.name } +func (k *Int16) Description() string { return k.description } + +func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int16) Get(lm label.Map) int16 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) } + +// Int32 represents a key +type Int32 struct { + name string + description string +} + +// NewInt32 creates a new Key for int32 values. +func NewInt32(name, description string) *Int32 { + return &Int32{name: name, description: description} +} + +func (k *Int32) Name() string { return k.name } +func (k *Int32) Description() string { return k.description } + +func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int32) Get(lm label.Map) int32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) } + +// Int64 represents a key +type Int64 struct { + name string + description string +} + +// NewInt64 creates a new Key for int64 values. +func NewInt64(name, description string) *Int64 { + return &Int64{name: name, description: description} +} + +func (k *Int64) Name() string { return k.name } +func (k *Int64) Description() string { return k.description } + +func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendInt(buf, k.From(l), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Int64) Get(lm label.Map) int64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) } + +// UInt represents a key +type UInt struct { + name string + description string +} + +// NewUInt creates a new Key for uint values. +func NewUInt(name, description string) *UInt { + return &UInt{name: name, description: description} +} + +func (k *UInt) Name() string { return k.name } +func (k *UInt) Description() string { return k.description } + +func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt) Get(lm label.Map) uint { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) } + +// UInt8 represents a key +type UInt8 struct { + name string + description string +} + +// NewUInt8 creates a new Key for uint8 values. +func NewUInt8(name, description string) *UInt8 { + return &UInt8{name: name, description: description} +} + +func (k *UInt8) Name() string { return k.name } +func (k *UInt8) Description() string { return k.description } + +func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt8) Get(lm label.Map) uint8 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) } + +// UInt16 represents a key +type UInt16 struct { + name string + description string +} + +// NewUInt16 creates a new Key for uint16 values. +func NewUInt16(name, description string) *UInt16 { + return &UInt16{name: name, description: description} +} + +func (k *UInt16) Name() string { return k.name } +func (k *UInt16) Description() string { return k.description } + +func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt16) Get(lm label.Map) uint16 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) } + +// UInt32 represents a key +type UInt32 struct { + name string + description string +} + +// NewUInt32 creates a new Key for uint32 values. +func NewUInt32(name, description string) *UInt32 { + return &UInt32{name: name, description: description} +} + +func (k *UInt32) Name() string { return k.name } +func (k *UInt32) Description() string { return k.description } + +func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt32) Get(lm label.Map) uint32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) } + +// UInt64 represents a key +type UInt64 struct { + name string + description string +} + +// NewUInt64 creates a new Key for uint64 values. +func NewUInt64(name, description string) *UInt64 { + return &UInt64{name: name, description: description} +} + +func (k *UInt64) Name() string { return k.name } +func (k *UInt64) Description() string { return k.description } + +func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendUint(buf, k.From(l), 10)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *UInt64) Get(lm label.Map) uint64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() } + +// Float32 represents a key +type Float32 struct { + name string + description string +} + +// NewFloat32 creates a new Key for float32 values. +func NewFloat32(name, description string) *Float32 { + return &Float32{name: name, description: description} +} + +func (k *Float32) Name() string { return k.name } +func (k *Float32) Description() string { return k.description } + +func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Float32) Of(v float32) label.Label { + return label.Of64(k, uint64(math.Float32bits(v))) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Float32) Get(lm label.Map) float32 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Float32) From(t label.Label) float32 { + return math.Float32frombits(uint32(t.Unpack64())) +} + +// Float64 represents a key +type Float64 struct { + name string + description string +} + +// NewFloat64 creates a new Key for int64 values. +func NewFloat64(name, description string) *Float64 { + return &Float64{name: name, description: description} +} + +func (k *Float64) Name() string { return k.name } +func (k *Float64) Description() string { return k.description } + +func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Float64) Of(v float64) label.Label { + return label.Of64(k, math.Float64bits(v)) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Float64) Get(lm label.Map) float64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From can be used to get a value from a Label. +func (k *Float64) From(t label.Label) float64 { + return math.Float64frombits(t.Unpack64()) +} + +// String represents a key +type String struct { + name string + description string +} + +// NewString creates a new Key for int64 values. +func NewString(name, description string) *String { + return &String{name: name, description: description} +} + +func (k *String) Name() string { return k.name } +func (k *String) Description() string { return k.description } + +func (k *String) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendQuote(buf, k.From(l))) +} + +// Of creates a new Label with this key and the supplied value. +func (k *String) Of(v string) label.Label { return label.OfString(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *String) Get(lm label.Map) string { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return "" +} + +// From can be used to get a value from a Label. +func (k *String) From(t label.Label) string { return t.UnpackString() } + +// Boolean represents a key +type Boolean struct { + name string + description string +} + +// NewBoolean creates a new Key for bool values. +func NewBoolean(name, description string) *Boolean { + return &Boolean{name: name, description: description} +} + +func (k *Boolean) Name() string { return k.name } +func (k *Boolean) Description() string { return k.description } + +func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) { + w.Write(strconv.AppendBool(buf, k.From(l))) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Boolean) Of(v bool) label.Label { + if v { + return label.Of64(k, 1) + } + return label.Of64(k, 0) +} + +// Get can be used to get a label for the key from a label.Map. +func (k *Boolean) Get(lm label.Map) bool { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return false +} + +// From can be used to get a value from a Label. +func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 } + +// Error represents a key +type Error struct { + name string + description string +} + +// NewError creates a new Key for int64 values. +func NewError(name, description string) *Error { + return &Error{name: name, description: description} +} + +func (k *Error) Name() string { return k.name } +func (k *Error) Description() string { return k.description } + +func (k *Error) Format(w io.Writer, buf []byte, l label.Label) { + io.WriteString(w, k.From(l).Error()) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } + +// Get can be used to get a label for the key from a label.Map. +func (k *Error) Get(lm label.Map) error { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From can be used to get a value from a Label. +func (k *Error) From(t label.Label) error { + err, _ := t.UnpackValue().(error) + return err +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go new file mode 100644 index 0000000..7e95866 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +var ( + // Msg is a key used to add message strings to label lists. + Msg = NewString("message", "a readable message") + // Label is a key used to indicate an event adds labels to the context. + Label = NewTag("label", "a label context marker") + // Start is used for things like traces that have a name. + Start = NewString("start", "span start") + // Metric is a key used to indicate an event records metrics. + End = NewTag("end", "a span end marker") + // Metric is a key used to indicate an event records metrics. + Detach = NewTag("detach", "a span detach marker") + // Err is a key used to add error values to label lists. + Err = NewError("error", "an error that occurred") + // Metric is a key used to indicate an event records metrics. + Metric = NewTag("metric", "a metric event marker") +) diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go new file mode 100644 index 0000000..b55c12e --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/label/label.go @@ -0,0 +1,213 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package label + +import ( + "fmt" + "io" + "reflect" + "unsafe" +) + +// Key is used as the identity of a Label. +// Keys are intended to be compared by pointer only, the name should be unique +// for communicating with external systems, but it is not required or enforced. +type Key interface { + // Name returns the key name. + Name() string + // Description returns a string that can be used to describe the value. + Description() string + + // Format is used in formatting to append the value of the label to the + // supplied buffer. + // The formatter may use the supplied buf as a scratch area to avoid + // allocations. + Format(w io.Writer, buf []byte, l Label) +} + +// Label holds a key and value pair. +// It is normally used when passing around lists of labels. +type Label struct { + key Key + packed uint64 + untyped interface{} +} + +// Map is the interface to a collection of Labels indexed by key. +type Map interface { + // Find returns the label that matches the supplied key. + Find(key Key) Label +} + +// List is the interface to something that provides an iterable +// list of labels. +// Iteration should start from 0 and continue until Valid returns false. +type List interface { + // Valid returns true if the index is within range for the list. + // It does not imply the label at that index will itself be valid. + Valid(index int) bool + // Label returns the label at the given index. + Label(index int) Label +} + +// list implements LabelList for a list of Labels. +type list struct { + labels []Label +} + +// filter wraps a LabelList filtering out specific labels. +type filter struct { + keys []Key + underlying List +} + +// listMap implements LabelMap for a simple list of labels. +type listMap struct { + labels []Label +} + +// mapChain implements LabelMap for a list of underlying LabelMap. +type mapChain struct { + maps []Map +} + +// OfValue creates a new label from the key and value. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} } + +// UnpackValue assumes the label was built using LabelOfValue and returns the value +// that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackValue() interface{} { return t.untyped } + +// Of64 creates a new label from a key and a uint64. This is often +// used for non uint64 values that can be packed into a uint64. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } + +// Unpack64 assumes the label was built using LabelOf64 and returns the value that +// was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) Unpack64() uint64 { return t.packed } + +// OfString creates a new label from a key and a string. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfString(k Key, v string) Label { + hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) + return Label{ + key: k, + packed: uint64(hdr.Len), + untyped: unsafe.Pointer(hdr.Data), + } +} + +// UnpackString assumes the label was built using LabelOfString and returns the +// value that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackString() string { + var v string + hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) + hdr.Data = uintptr(t.untyped.(unsafe.Pointer)) + hdr.Len = int(t.packed) + return *(*string)(unsafe.Pointer(hdr)) +} + +// Valid returns true if the Label is a valid one (it has a key). +func (t Label) Valid() bool { return t.key != nil } + +// Key returns the key of this Label. +func (t Label) Key() Key { return t.key } + +// Format is used for debug printing of labels. +func (t Label) Format(f fmt.State, r rune) { + if !t.Valid() { + io.WriteString(f, `nil`) + return + } + io.WriteString(f, t.Key().Name()) + io.WriteString(f, "=") + var buf [128]byte + t.Key().Format(f, buf[:0], t) +} + +func (l *list) Valid(index int) bool { + return index >= 0 && index < len(l.labels) +} + +func (l *list) Label(index int) Label { + return l.labels[index] +} + +func (f *filter) Valid(index int) bool { + return f.underlying.Valid(index) +} + +func (f *filter) Label(index int) Label { + l := f.underlying.Label(index) + for _, f := range f.keys { + if l.Key() == f { + return Label{} + } + } + return l +} + +func (lm listMap) Find(key Key) Label { + for _, l := range lm.labels { + if l.Key() == key { + return l + } + } + return Label{} +} + +func (c mapChain) Find(key Key) Label { + for _, src := range c.maps { + l := src.Find(key) + if l.Valid() { + return l + } + } + return Label{} +} + +var emptyList = &list{} + +func NewList(labels ...Label) List { + if len(labels) == 0 { + return emptyList + } + return &list{labels: labels} +} + +func Filter(l List, keys ...Key) List { + if len(keys) == 0 { + return l + } + return &filter{keys: keys, underlying: l} +} + +func NewMap(labels ...Label) Map { + return listMap{labels: labels} +} + +func MergeMaps(srcs ...Map) Map { + var nonNil []Map + for _, src := range srcs { + if src != nil { + nonNil = append(nonNil, src) + } + } + if len(nonNil) == 1 { + return nonNil[0] + } + return mapChain{maps: nonNil} +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go new file mode 100644 index 0000000..f516e17 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -0,0 +1,230 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gocommand is a helper for calling the go command. +package gocommand + +import ( + "bytes" + "context" + "fmt" + "io" + "os" + "os/exec" + "regexp" + "strings" + "sync" + "time" + + "golang.org/x/tools/internal/event" +) + +// An Runner will run go command invocations and serialize +// them if it sees a concurrency error. +type Runner struct { + // once guards the runner initialization. + once sync.Once + + // inFlight tracks available workers. + inFlight chan struct{} + + // serialized guards the ability to run a go command serially, + // to avoid deadlocks when claiming workers. + serialized chan struct{} +} + +const maxInFlight = 10 + +func (runner *Runner) initialize() { + runner.once.Do(func() { + runner.inFlight = make(chan struct{}, maxInFlight) + runner.serialized = make(chan struct{}, 1) + }) +} + +// 1.13: go: updates to go.mod needed, but contents have changed +// 1.14: go: updating go.mod: existing contents have changed since last read +var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) + +// Run is a convenience wrapper around RunRaw. +// It returns only stdout and a "friendly" error. +func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { + stdout, _, friendly, _ := runner.RunRaw(ctx, inv) + return stdout, friendly +} + +// RunPiped runs the invocation serially, always waiting for any concurrent +// invocations to complete first. +func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { + _, err := runner.runPiped(ctx, inv, stdout, stderr) + return err +} + +// RunRaw runs the invocation, serializing requests only if they fight over +// go.mod changes. +func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + // Make sure the runner is always initialized. + runner.initialize() + + // First, try to run the go command concurrently. + stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) + + // If we encounter a load concurrency error, we need to retry serially. + if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) { + return stdout, stderr, friendlyErr, err + } + event.Error(ctx, "Load concurrency error, will retry serially", err) + + // Run serially by calling runPiped. + stdout.Reset() + stderr.Reset() + friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) + return stdout, stderr, friendlyErr, err +} + +func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + // Wait for 1 worker to become available. + select { + case <-ctx.Done(): + return nil, nil, nil, ctx.Err() + case runner.inFlight <- struct{}{}: + defer func() { <-runner.inFlight }() + } + + stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} + friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) + return stdout, stderr, friendlyErr, err +} + +func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { + // Make sure the runner is always initialized. + runner.initialize() + + // Acquire the serialization lock. This avoids deadlocks between two + // runPiped commands. + select { + case <-ctx.Done(): + return nil, ctx.Err() + case runner.serialized <- struct{}{}: + defer func() { <-runner.serialized }() + } + + // Wait for all in-progress go commands to return before proceeding, + // to avoid load concurrency errors. + for i := 0; i < maxInFlight; i++ { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case runner.inFlight <- struct{}{}: + // Make sure we always "return" any workers we took. + defer func() { <-runner.inFlight }() + } + } + + return inv.runWithFriendlyError(ctx, stdout, stderr) +} + +// An Invocation represents a call to the go command. +type Invocation struct { + Verb string + Args []string + BuildFlags []string + Env []string + WorkingDir string + Logf func(format string, args ...interface{}) +} + +func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { + rawError = i.run(ctx, stdout, stderr) + if rawError != nil { + friendlyError = rawError + // Check for 'go' executable not being found. + if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + friendlyError = fmt.Errorf("go command required, not found: %v", ee) + } + if ctx.Err() != nil { + friendlyError = ctx.Err() + } + friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) + } + return +} + +func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { + log := i.Logf + if log == nil { + log = func(string, ...interface{}) {} + } + + goArgs := []string{i.Verb} + switch i.Verb { + case "mod": + // mod needs the sub-verb before build flags. + goArgs = append(goArgs, i.Args[0]) + goArgs = append(goArgs, i.BuildFlags...) + goArgs = append(goArgs, i.Args[1:]...) + case "env": + // env doesn't take build flags. + goArgs = append(goArgs, i.Args...) + default: + goArgs = append(goArgs, i.BuildFlags...) + goArgs = append(goArgs, i.Args...) + } + cmd := exec.Command("go", goArgs...) + cmd.Stdout = stdout + cmd.Stderr = stderr + // On darwin the cwd gets resolved to the real path, which breaks anything that + // expects the working directory to keep the original path, including the + // go command when dealing with modules. + // The Go stdlib has a special feature where if the cwd and the PWD are the + // same node then it trusts the PWD, so by setting it in the env for the child + // process we fix up all the paths returned by the go command. + cmd.Env = append(os.Environ(), i.Env...) + if i.WorkingDir != "" { + cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) + cmd.Dir = i.WorkingDir + } + defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) + + return runCmdContext(ctx, cmd) +} + +// runCmdContext is like exec.CommandContext except it sends os.Interrupt +// before os.Kill. +func runCmdContext(ctx context.Context, cmd *exec.Cmd) error { + if err := cmd.Start(); err != nil { + return err + } + resChan := make(chan error, 1) + go func() { + resChan <- cmd.Wait() + }() + + select { + case err := <-resChan: + return err + case <-ctx.Done(): + } + // Cancelled. Interrupt and see if it ends voluntarily. + cmd.Process.Signal(os.Interrupt) + select { + case err := <-resChan: + return err + case <-time.After(time.Second): + } + // Didn't shut down in response to interrupt. Kill it hard. + cmd.Process.Kill() + return <-resChan +} + +func cmdDebugStr(cmd *exec.Cmd) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.Split(kv, "=") + k, v := split[0], split[1] + env[k] = v + } + + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v go %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], cmd.Args) +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go new file mode 100644 index 0000000..1cd8d84 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -0,0 +1,102 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gocommand + +import ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "golang.org/x/mod/semver" +) + +// ModuleJSON holds information about a module. +type ModuleJSON struct { + Path string // module path + Replace *ModuleJSON // replaced by this module + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file for this module, if any + GoVersion string // go version used in module +} + +var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) + +// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands +// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, +// of which only Verb and Args are modified to run the appropriate Go command. +// Inspired by setDefaultBuildMod in modload/init.go +func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { + mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) + if err != nil { + return nil, false, err + } + + // We check the GOFLAGS to see if there is anything overridden or not. + inv.Verb = "env" + inv.Args = []string{"GOFLAGS"} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, false, err + } + goflags := string(bytes.TrimSpace(stdout.Bytes())) + matches := modFlagRegexp.FindStringSubmatch(goflags) + var modFlag string + if len(matches) != 0 { + modFlag = matches[1] + } + if modFlag != "" { + // Don't override an explicit '-mod=' argument. + return mainMod, modFlag == "vendor", nil + } + if mainMod == nil || !go114 { + return mainMod, false, nil + } + // Check 1.14's automatic vendor mode. + if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { + if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { + // The Go version is at least 1.14, and a vendor directory exists. + // Set -mod=vendor by default. + return mainMod, true, nil + } + } + return mainMod, false, nil +} + +// getMainModuleAnd114 gets the main module's information and whether the +// go command in use is 1.14+. This is the information needed to figure out +// if vendoring should be enabled. +func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { + const format = `{{.Path}} +{{.Dir}} +{{.GoMod}} +{{.GoVersion}} +{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} +` + inv.Verb = "list" + inv.Args = []string{"-m", "-f", format} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, false, err + } + + lines := strings.Split(stdout.String(), "\n") + if len(lines) < 5 { + return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) + } + mod := &ModuleJSON{ + Path: lines[0], + Dir: lines[1], + GoMod: lines[2], + GoVersion: lines[3], + Main: true, + } + return mod, lines[4] == "go1.14", nil +} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go new file mode 100644 index 0000000..2c4527f --- /dev/null +++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go @@ -0,0 +1,14 @@ +// Package packagesinternal exposes internal-only fields from go/packages. +package packagesinternal + +import ( + "golang.org/x/tools/internal/gocommand" +) + +var GetForTest = func(p interface{}) string { return "" } + +var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil } + +var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {} + +var TypecheckCgo int diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go new file mode 100644 index 0000000..a5bb408 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -0,0 +1,28 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typesinternal + +import ( + "go/types" + "reflect" + "unsafe" +) + +func SetUsesCgo(conf *types.Config) bool { + v := reflect.ValueOf(conf).Elem() + + f := v.FieldByName("go115UsesCgo") + if !f.IsValid() { + f = v.FieldByName("UsesCgo") + if !f.IsValid() { + return false + } + } + + addr := unsafe.Pointer(f.UnsafeAddr()) + *(*bool)(addr) = true + + return true +} diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/xerrors/LICENSE new file mode 100644 index 0000000..e4a47e1 --- /dev/null +++ b/vendor/golang.org/x/xerrors/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Go Authors. 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 Google Inc. 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 +OWNER 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/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/xerrors/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/xerrors/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/xerrors/README b/vendor/golang.org/x/xerrors/README new file mode 100644 index 0000000..aac7867 --- /dev/null +++ b/vendor/golang.org/x/xerrors/README @@ -0,0 +1,2 @@ +This repository holds the transition packages for the new Go 1.13 error values. +See golang.org/design/29934-error-values. diff --git a/vendor/golang.org/x/xerrors/adaptor.go b/vendor/golang.org/x/xerrors/adaptor.go new file mode 100644 index 0000000..4317f24 --- /dev/null +++ b/vendor/golang.org/x/xerrors/adaptor.go @@ -0,0 +1,193 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strconv" +) + +// FormatError calls the FormatError method of f with an errors.Printer +// configured according to s and verb, and writes the result to s. +func FormatError(f Formatter, s fmt.State, verb rune) { + // Assuming this function is only called from the Format method, and given + // that FormatError takes precedence over Format, it cannot be called from + // any package that supports errors.Formatter. It is therefore safe to + // disregard that State may be a specific printer implementation and use one + // of our choice instead. + + // limitations: does not support printing error as Go struct. + + var ( + sep = " " // separator before next error + p = &state{State: s} + direct = true + ) + + var err error = f + + switch verb { + // Note that this switch must match the preference order + // for ordinary string printing (%#v before %+v, and so on). + + case 'v': + if s.Flag('#') { + if stringer, ok := err.(fmt.GoStringer); ok { + io.WriteString(&p.buf, stringer.GoString()) + goto exit + } + // proceed as if it were %v + } else if s.Flag('+') { + p.printDetail = true + sep = "\n - " + } + case 's': + case 'q', 'x', 'X': + // Use an intermediate buffer in the rare cases that precision, + // truncation, or one of the alternative verbs (q, x, and X) are + // specified. + direct = false + + default: + p.buf.WriteString("%!") + p.buf.WriteRune(verb) + p.buf.WriteByte('(') + switch { + case err != nil: + p.buf.WriteString(reflect.TypeOf(f).String()) + default: + p.buf.WriteString("") + } + p.buf.WriteByte(')') + io.Copy(s, &p.buf) + return + } + +loop: + for { + switch v := err.(type) { + case Formatter: + err = v.FormatError((*printer)(p)) + case fmt.Formatter: + v.Format(p, 'v') + break loop + default: + io.WriteString(&p.buf, v.Error()) + break loop + } + if err == nil { + break + } + if p.needColon || !p.printDetail { + p.buf.WriteByte(':') + p.needColon = false + } + p.buf.WriteString(sep) + p.inDetail = false + p.needNewline = false + } + +exit: + width, okW := s.Width() + prec, okP := s.Precision() + + if !direct || (okW && width > 0) || okP { + // Construct format string from State s. + format := []byte{'%'} + if s.Flag('-') { + format = append(format, '-') + } + if s.Flag('+') { + format = append(format, '+') + } + if s.Flag(' ') { + format = append(format, ' ') + } + if okW { + format = strconv.AppendInt(format, int64(width), 10) + } + if okP { + format = append(format, '.') + format = strconv.AppendInt(format, int64(prec), 10) + } + format = append(format, string(verb)...) + fmt.Fprintf(s, string(format), p.buf.String()) + } else { + io.Copy(s, &p.buf) + } +} + +var detailSep = []byte("\n ") + +// state tracks error printing state. It implements fmt.State. +type state struct { + fmt.State + buf bytes.Buffer + + printDetail bool + inDetail bool + needColon bool + needNewline bool +} + +func (s *state) Write(b []byte) (n int, err error) { + if s.printDetail { + if len(b) == 0 { + return 0, nil + } + if s.inDetail && s.needColon { + s.needNewline = true + if b[0] == '\n' { + b = b[1:] + } + } + k := 0 + for i, c := range b { + if s.needNewline { + if s.inDetail && s.needColon { + s.buf.WriteByte(':') + s.needColon = false + } + s.buf.Write(detailSep) + s.needNewline = false + } + if c == '\n' { + s.buf.Write(b[k:i]) + k = i + 1 + s.needNewline = true + } + } + s.buf.Write(b[k:]) + if !s.inDetail { + s.needColon = true + } + } else if !s.inDetail { + s.buf.Write(b) + } + return len(b), nil +} + +// printer wraps a state to implement an xerrors.Printer. +type printer state + +func (s *printer) Print(args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprint((*state)(s), args...) + } +} + +func (s *printer) Printf(format string, args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprintf((*state)(s), format, args...) + } +} + +func (s *printer) Detail() bool { + s.inDetail = true + return s.printDetail +} diff --git a/vendor/golang.org/x/xerrors/codereview.cfg b/vendor/golang.org/x/xerrors/codereview.cfg new file mode 100644 index 0000000..3f8b14b --- /dev/null +++ b/vendor/golang.org/x/xerrors/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/vendor/golang.org/x/xerrors/doc.go b/vendor/golang.org/x/xerrors/doc.go new file mode 100644 index 0000000..eef99d9 --- /dev/null +++ b/vendor/golang.org/x/xerrors/doc.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xerrors implements functions to manipulate errors. +// +// This package is based on the Go 2 proposal for error values: +// https://golang.org/design/29934-error-values +// +// These functions were incorporated into the standard library's errors package +// in Go 1.13: +// - Is +// - As +// - Unwrap +// +// Also, Errorf's %w verb was incorporated into fmt.Errorf. +// +// Use this package to get equivalent behavior in all supported Go versions. +// +// No other features of this package were included in Go 1.13, and at present +// there are no plans to include any of them. +package xerrors // import "golang.org/x/xerrors" diff --git a/vendor/golang.org/x/xerrors/errors.go b/vendor/golang.org/x/xerrors/errors.go new file mode 100644 index 0000000..e88d377 --- /dev/null +++ b/vendor/golang.org/x/xerrors/errors.go @@ -0,0 +1,33 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import "fmt" + +// errorString is a trivial implementation of error. +type errorString struct { + s string + frame Frame +} + +// New returns an error that formats as the given text. +// +// The returned error contains a Frame set to the caller's location and +// implements Formatter to show this information when printed with details. +func New(text string) error { + return &errorString{text, Caller(1)} +} + +func (e *errorString) Error() string { + return e.s +} + +func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *errorString) FormatError(p Printer) (next error) { + p.Print(e.s) + e.frame.Format(p) + return nil +} diff --git a/vendor/golang.org/x/xerrors/fmt.go b/vendor/golang.org/x/xerrors/fmt.go new file mode 100644 index 0000000..829862d --- /dev/null +++ b/vendor/golang.org/x/xerrors/fmt.go @@ -0,0 +1,187 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "fmt" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/xerrors/internal" +) + +const percentBangString = "%!" + +// Errorf formats according to a format specifier and returns the string as a +// value that satisfies error. +// +// The returned error includes the file and line number of the caller when +// formatted with additional detail enabled. If the last argument is an error +// the returned error's Format method will return it if the format string ends +// with ": %s", ": %v", or ": %w". If the last argument is an error and the +// format string ends with ": %w", the returned error implements an Unwrap +// method returning it. +// +// If the format specifier includes a %w verb with an error operand in a +// position other than at the end, the returned error will still implement an +// Unwrap method returning the operand, but the error's Format method will not +// return the wrapped error. +// +// It is invalid to include more than one %w verb or to supply it with an +// operand that does not implement the error interface. The %w verb is otherwise +// a synonym for %v. +func Errorf(format string, a ...interface{}) error { + format = formatPlusW(format) + // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. + wrap := strings.HasSuffix(format, ": %w") + idx, format2, ok := parsePercentW(format) + percentWElsewhere := !wrap && idx >= 0 + if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { + err := errorAt(a, len(a)-1) + if err == nil { + return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + } + // TODO: this is not entirely correct. The error value could be + // printed elsewhere in format if it mixes numbered with unnumbered + // substitutions. With relatively small changes to doPrintf we can + // have it optionally ignore extra arguments and pass the argument + // list in its entirety. + msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + if wrap { + return &wrapError{msg, err, frame} + } + return &noWrapError{msg, err, frame} + } + // Support %w anywhere. + // TODO: don't repeat the wrapped error's message when %w occurs in the middle. + msg := fmt.Sprintf(format2, a...) + if idx < 0 { + return &noWrapError{msg, nil, Caller(1)} + } + err := errorAt(a, idx) + if !ok || err == nil { + // Too many %ws or argument of %w is not an error. Approximate the Go + // 1.13 fmt.Errorf message. + return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} + } + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + return &wrapError{msg, err, frame} +} + +func errorAt(args []interface{}, i int) error { + if i < 0 || i >= len(args) { + return nil + } + err, ok := args[i].(error) + if !ok { + return nil + } + return err +} + +// formatPlusW is used to avoid the vet check that will barf at %w. +func formatPlusW(s string) string { + return s +} + +// Return the index of the only %w in format, or -1 if none. +// Also return a rewritten format string with %w replaced by %v, and +// false if there is more than one %w. +// TODO: handle "%[N]w". +func parsePercentW(format string) (idx int, newFormat string, ok bool) { + // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. + idx = -1 + ok = true + n := 0 + sz := 0 + var isW bool + for i := 0; i < len(format); i += sz { + if format[i] != '%' { + sz = 1 + continue + } + // "%%" is not a format directive. + if i+1 < len(format) && format[i+1] == '%' { + sz = 2 + continue + } + sz, isW = parsePrintfVerb(format[i:]) + if isW { + if idx >= 0 { + ok = false + } else { + idx = n + } + // "Replace" the last character, the 'w', with a 'v'. + p := i + sz - 1 + format = format[:p] + "v" + format[p+1:] + } + n++ + } + return idx, format, ok +} + +// Parse the printf verb starting with a % at s[0]. +// Return how many bytes it occupies and whether the verb is 'w'. +func parsePrintfVerb(s string) (int, bool) { + // Assume only that the directive is a sequence of non-letters followed by a single letter. + sz := 0 + var r rune + for i := 1; i < len(s); i += sz { + r, sz = utf8.DecodeRuneInString(s[i:]) + if unicode.IsLetter(r) { + return i + sz, r == 'w' + } + } + return len(s), false +} + +type noWrapError struct { + msg string + err error + frame Frame +} + +func (e *noWrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *noWrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +type wrapError struct { + msg string + err error + frame Frame +} + +func (e *wrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *wrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +func (e *wrapError) Unwrap() error { + return e.err +} diff --git a/vendor/golang.org/x/xerrors/format.go b/vendor/golang.org/x/xerrors/format.go new file mode 100644 index 0000000..1bc9c26 --- /dev/null +++ b/vendor/golang.org/x/xerrors/format.go @@ -0,0 +1,34 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +// A Formatter formats error messages. +type Formatter interface { + error + + // FormatError prints the receiver's first error and returns the next error in + // the error chain, if any. + FormatError(p Printer) (next error) +} + +// A Printer formats error messages. +// +// The most common implementation of Printer is the one provided by package fmt +// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message +// typically provide their own implementations. +type Printer interface { + // Print appends args to the message output. + Print(args ...interface{}) + + // Printf writes a formatted string. + Printf(format string, args ...interface{}) + + // Detail reports whether error detail is requested. + // After the first call to Detail, all text written to the Printer + // is formatted as additional detail, or ignored when + // detail has not been requested. + // If Detail returns false, the caller can avoid printing the detail at all. + Detail() bool +} diff --git a/vendor/golang.org/x/xerrors/frame.go b/vendor/golang.org/x/xerrors/frame.go new file mode 100644 index 0000000..0de628e --- /dev/null +++ b/vendor/golang.org/x/xerrors/frame.go @@ -0,0 +1,56 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "runtime" +) + +// A Frame contains part of a call stack. +type Frame struct { + // Make room for three PCs: the one we were asked for, what it called, + // and possibly a PC for skipPleaseUseCallersFrames. See: + // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 + frames [3]uintptr +} + +// Caller returns a Frame that describes a frame on the caller's stack. +// The argument skip is the number of frames to skip over. +// Caller(0) returns the frame for the caller of Caller. +func Caller(skip int) Frame { + var s Frame + runtime.Callers(skip+1, s.frames[:]) + return s +} + +// location reports the file, line, and function of a frame. +// +// The returned function may be "" even if file and line are not. +func (f Frame) location() (function, file string, line int) { + frames := runtime.CallersFrames(f.frames[:]) + if _, ok := frames.Next(); !ok { + return "", "", 0 + } + fr, ok := frames.Next() + if !ok { + return "", "", 0 + } + return fr.Function, fr.File, fr.Line +} + +// Format prints the stack as error detail. +// It should be called from an error's Format implementation +// after printing any other error detail. +func (f Frame) Format(p Printer) { + if p.Detail() { + function, file, line := f.location() + if function != "" { + p.Printf("%s\n ", function) + } + if file != "" { + p.Printf("%s:%d\n", file, line) + } + } +} diff --git a/vendor/golang.org/x/xerrors/go.mod b/vendor/golang.org/x/xerrors/go.mod new file mode 100644 index 0000000..870d4f6 --- /dev/null +++ b/vendor/golang.org/x/xerrors/go.mod @@ -0,0 +1,3 @@ +module golang.org/x/xerrors + +go 1.11 diff --git a/vendor/golang.org/x/xerrors/internal/internal.go b/vendor/golang.org/x/xerrors/internal/internal.go new file mode 100644 index 0000000..89f4eca --- /dev/null +++ b/vendor/golang.org/x/xerrors/internal/internal.go @@ -0,0 +1,8 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +// EnableTrace indicates whether stack information should be recorded in errors. +var EnableTrace = true diff --git a/vendor/golang.org/x/xerrors/wrap.go b/vendor/golang.org/x/xerrors/wrap.go new file mode 100644 index 0000000..9a3b510 --- /dev/null +++ b/vendor/golang.org/x/xerrors/wrap.go @@ -0,0 +1,106 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "reflect" +) + +// A Wrapper provides context around another error. +type Wrapper interface { + // Unwrap returns the next error in the error chain. + // If there is no next error, Unwrap returns nil. + Unwrap() error +} + +// Opaque returns an error with the same error formatting as err +// but that does not match err and cannot be unwrapped. +func Opaque(err error) error { + return noWrapper{err} +} + +type noWrapper struct { + error +} + +func (e noWrapper) FormatError(p Printer) (next error) { + if f, ok := e.error.(Formatter); ok { + return f.FormatError(p) + } + p.Print(e.error) + return nil +} + +// Unwrap returns the result of calling the Unwrap method on err, if err implements +// Unwrap. Otherwise, Unwrap returns nil. +func Unwrap(err error) error { + u, ok := err.(Wrapper) + if !ok { + return nil + } + return u.Unwrap() +} + +// Is reports whether any error in err's chain matches target. +// +// An error is considered to match a target if it is equal to that target or if +// it implements a method Is(error) bool such that Is(target) returns true. +func Is(err, target error) bool { + if target == nil { + return err == target + } + + isComparable := reflect.TypeOf(target).Comparable() + for { + if isComparable && err == target { + return true + } + if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { + return true + } + // TODO: consider supporing target.Is(err). This would allow + // user-definable predicates, but also may allow for coping with sloppy + // APIs, thereby making it easier to get away with them. + if err = Unwrap(err); err == nil { + return false + } + } +} + +// As finds the first error in err's chain that matches the type to which target +// points, and if so, sets the target to its value and returns true. An error +// matches a type if it is assignable to the target type, or if it has a method +// As(interface{}) bool such that As(target) returns true. As will panic if target +// is not a non-nil pointer to a type which implements error or is of interface type. +// +// The As method should set the target to its value and return true if err +// matches the type to which target points. +func As(err error, target interface{}) bool { + if target == nil { + panic("errors: target cannot be nil") + } + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + panic("errors: target must be a non-nil pointer") + } + if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { + panic("errors: *target must be interface or implement error") + } + targetType := typ.Elem() + for err != nil { + if reflect.TypeOf(err).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(err)) + return true + } + if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { + return true + } + err = Unwrap(err) + } + return false +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem()