1#! /usr/bin/env python
2# x86 instructions and prefixes data and code generation
3#
4#  Copyright (C) 2002-2007  Peter Johnson
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27# NOTE: operands are arranged in NASM / Intel order (e.g. dest, src)
28
29import os
30import sys
31
32from sys import stdout, version_info
33
34scriptname = "gen_x86_insn.py"
35scriptrev = "HEAD"
36
37ordered_cpus = [
38    "086", "186", "286", "386", "486", "586", "686", "K6", "Athlon", "P3",
39    "P4", "IA64", "Hammer"]
40ordered_cpu_features = [
41    "FPU", "Cyrix", "AMD", "MMX", "3DNow", "SMM", "SSE", "SSE2",
42    "SSE3", "SVM", "PadLock", "SSSE3", "SSE41", "SSE42", "SSE4a", "SSE5",
43    "AVX", "FMA", "AES", "CLMUL", "MOVBE", "XOP", "FMA4", "F16C",
44    "FSGSBASE", "RDRAND", "XSAVEOPT", "EPTVPID", "SMX", "AVX2", "BMI1",
45    "BMI2", "INVPCID", "LZCNT"]
46unordered_cpu_features = ["Priv", "Prot", "Undoc", "Obs"]
47
48# Predefined VEX prefix field values
49VEXW0 = 0xC0
50VEXW1 = 0xC8
51VEXL0 = 0xC0
52VEXL1 = 0xC4
53VEXpp = 0xC0    # OR with value
54
55# Predefined XOP prefix field values
56XOPW0 = 0x80
57XOPW1 = 0x88
58XOPL0 = 0x80
59XOPL1 = 0x84
60XOPpp = 0x80    # OR with value
61
62def lprint(s, f = stdout, e = '\n') :
63    f.write(s + e)
64
65def cpu_lcd(cpu1, cpu2):
66    """Find the lowest common denominator of two CPU sets."""
67    retval = set()
68
69    # CPU
70    cpu1cpus = set(ordered_cpus) & set(cpu1)
71    if not cpu1cpus:
72        cpu1cpus.add("086")
73    cpu1mincpu = min(ordered_cpus.index(x) for x in cpu1cpus)
74    cpu2cpus = set(ordered_cpus) & set(cpu2)
75    if not cpu2cpus:
76        cpu2cpus.add("086")
77    cpu2mincpu = min(ordered_cpus.index(x) for x in cpu1cpus)
78    cpumin = ordered_cpus[min(cpu1mincpu, cpu2mincpu)]
79    if cpumin == "086":
80        cpumin = "Any"
81
82    if cpumin != "Any":
83        retval.add(cpumin)
84
85    # Feature
86    cpu1features = set(ordered_cpu_features) & set(cpu1)
87    if not cpu1features:
88        cpu1minfeature = -1
89    else:
90        cpu1minfeature = min(ordered_cpu_features.index(x)
91                             for x in cpu1features)
92
93    cpu2features = set(ordered_cpu_features) & set(cpu2)
94    if not cpu2features:
95        cpu2minfeature = -1
96    else:
97        cpu2minfeature = min(ordered_cpu_features.index(x)
98                             for x in cpu2features)
99
100    if cpu1minfeature != -1 and cpu2minfeature != -1:
101        featuremin = ordered_cpu_features[min(cpu1minfeature, cpu2minfeature)]
102        retval.add(featuremin)
103
104    # Unordered features
105    for feature in set(unordered_cpu_features) & set(cpu1) & set(cpu2):
106        retval.add(feature)
107
108    return retval
109
110class Operand(object):
111    def __init__(self, **kwargs):
112        self.type = kwargs.pop("type")
113        self.size = kwargs.pop("size", "Any")
114        self.relaxed = kwargs.pop("relaxed", False)
115        self.dest = kwargs.pop("dest", None)
116        self.tmod = kwargs.pop("tmod", None)
117        self.opt = kwargs.pop("opt", None)
118
119        if kwargs:
120            for arg in kwargs:
121                lprint("Warning: unrecognized arg %s" % arg)
122
123    def __str__(self):
124        return "{"+ ", ".join(["OPT_%s" % self.type,
125                               "OPS_%s" % self.size,
126                               "%d" % self.relaxed,
127                               self.dest == "EA64" and "1" or "0",
128                               "OPTM_%s" % self.tmod,
129                               "OPA_%s" % (self.dest == "EA64"
130                                           and "EA" or self.dest),
131                               "OPAP_%s" % self.opt]) + "}"
132
133    def __eq__(self, other):
134        return (self.type == other.type and
135                self.size == other.size and
136                self.relaxed == other.relaxed and
137                self.dest == other.dest and
138                self.tmod == other.tmod and
139                self.opt == other.opt)
140
141    def __ne__(self, other):
142        return (self.type != other.type or
143                self.size != other.size or
144                self.relaxed != other.relaxed or
145                self.dest != other.dest or
146                self.tmod != other.tmod or
147                self.opt != other.opt)
148
149class GroupForm(object):
150    def __init__(self, **kwargs):
151        # Parsers
152        self.parsers = set(kwargs.pop("parsers", ["gas", "nasm"]))
153
154        # CPU feature flags initialization
155        self.cpu = set(kwargs.pop("cpu", []))
156
157        # Misc flags
158        self.misc_flags = set(kwargs.pop("misc_flags", []))
159        if kwargs.pop("only64", False):
160            self.misc_flags.add("ONLY_64")
161        if kwargs.pop("not64", False):
162            self.misc_flags.add("NOT_64")
163        if kwargs.pop("onlyavx", False):
164            self.misc_flags.add("ONLY_AVX")
165        if kwargs.pop("notavx", False):
166            self.misc_flags.add("NOT_AVX")
167
168        # Operation size
169        self.opersize = kwargs.pop("opersize", 0)
170        if self.opersize == 8:
171            self.opersize = 0
172
173        if self.opersize == 64:
174            self.misc_flags.add("ONLY_64")
175        elif self.opersize == 32 and "ONLY_64" not in self.misc_flags:
176            self.cpu.add("386")
177
178        # Default operation size in 64-bit mode
179        self.def_opersize_64 = kwargs.pop("def_opersize_64", 0)
180
181        # GAS suffix
182        self.gen_suffix = kwargs.pop("gen_suffix", True)
183        self.suffixes = kwargs.pop("suffixes", None)
184        suffix = kwargs.pop("suffix", None)
185        if suffix is not None:
186            self.suffixes = [suffix]
187
188        req_suffix = kwargs.pop("req_suffix", False)
189        if not req_suffix:
190            if self.suffixes is None:
191                self.suffixes = ["Z"]
192            else:
193                self.suffixes.append("Z")
194
195        if self.suffixes is not None:
196            self.suffixes = set(x.upper() for x in self.suffixes)
197
198        # Special instruction prefix
199        self.special_prefix = "0"
200        if "prefix" in kwargs:
201            self.special_prefix = "0x%02X" % kwargs.pop("prefix")
202
203        # VEX prefix
204        if "vex" in kwargs:
205            self.misc_flags.add("ONLY_AVX")
206            vexW = kwargs.pop("vexw", 0)
207            if vexW not in [0, 1]:
208                raise ValueError("VEX.W must be 0 or 1")
209
210            vexL = kwargs.pop("vex")
211            if vexL == 128 or vexL == 0:
212                vexL = 0
213            elif vexL == 256:
214                vexL = 1
215            else:
216                raise ValueError("VEX.L must be 128 or 256")
217
218            if self.special_prefix in ["0", "0x00"]:
219                vexpp = 0
220            elif self.special_prefix == "0x66":
221                vexpp = 1
222            elif self.special_prefix == "0xF3":
223                vexpp = 2
224            elif self.special_prefix == "0xF2":
225                vexpp = 3
226            else:
227                raise ValueError("Cannot combine VEX and special prefix %s"
228                                 % self.special_prefix)
229
230            self.special_prefix = "0x%02X" % (0xC0 + vexW*8 + vexL*4 + vexpp)
231
232        # XOP prefix
233        if "xop" in kwargs:
234            xopW = kwargs.pop("xopw", 0)
235            if xopW not in [0, 1]:
236                raise ValueError("XOP.W must be 0 or 1")
237
238            xopL = kwargs.pop("xop")
239            if xopL == 128 or xopL == 0:
240                xopL = 0
241            elif xopL == 256:
242                xopL = 1
243            else:
244                raise ValueError("XOP.L must be 128 or 256")
245
246            # XOPpp is currently reserved (0)
247            xoppp = 0
248            if self.special_prefix not in ["0", "0x00"]:
249                raise ValueError("Cannot combine XOP and special prefix %s"
250                                 % self.special_prefix)
251            self.special_prefix = "0x%02X" % (0x80 + xopW*8 + xopL*4 + xoppp)
252
253        # Spare value
254        self.spare = kwargs.pop("spare", 0)
255
256        # Build opcodes string (C array initializer)
257        if "opcode" in kwargs:
258            # Usual case, just a single opcode
259            self.opcode = kwargs.pop("opcode")
260            self.opcode_len = len(self.opcode)
261        elif "opcode1" in kwargs and "opcode2" in kwargs:
262            # Two opcode case; the first opcode is the "optimized" opcode,
263            # the second is the "relaxed" opcode.  For this to work, an
264            # opt="foo" must be set for one of the operands.
265            self.opcode1 = kwargs.pop("opcode1")
266            self.opcode2 = kwargs.pop("opcode2")
267            self.opcode_len = len(self.opcode1)
268        else:
269            raise KeyError("missing opcode")
270
271        # Build operands string (C array initializer)
272        self.operands = kwargs.pop("operands")
273        for op in self.operands:
274            if op.type in ["Reg", "RM", "Areg", "Creg", "Dreg"]:
275                if op.size == 64:
276                    self.misc_flags.add("ONLY_64")
277                elif op.size == 32 and "ONLY_64" not in self.misc_flags:
278                    self.cpu.add("386")
279            if op.type in ["Imm", "ImmNotSegOff"]:
280                if op.size == 64:
281                    self.misc_flags.add("ONLY_64")
282                elif op.size == 32 and "ONLY_64" not in self.misc_flags:
283                    self.cpu.add("386")
284            if op.type in ["FS", "GS"] and "ONLY_64" not in self.misc_flags:
285                self.cpu.add("386")
286            if op.type in ["CR4"] and "ONLY_64" not in self.misc_flags:
287                self.cpu.add("586")
288            if op.dest == "EA64":
289                self.misc_flags.add("ONLY_64")
290
291        # Modifiers
292        self.modifiers = kwargs.pop("modifiers", [])
293
294        # GAS flags
295        self.gas_only = ("nasm" not in self.parsers)
296        self.gas_illegal = ("gas" not in self.parsers)
297        self.gas_no_rev = (kwargs.pop("gas_no_reverse", False) or
298                           kwargs.pop("gas_no_rev", False))
299
300        # CPU feature flags finalization
301        # Remove redundancies
302        maxcpu = -1
303        maxcpu_set = self.cpu & set(ordered_cpus)
304        if maxcpu_set:
305            maxcpu = max(ordered_cpus.index(x) for x in maxcpu_set)
306        if maxcpu != -1:
307            for cpu in ordered_cpus[0:maxcpu]:
308                self.cpu.discard(cpu)
309
310        if kwargs:
311            for arg in kwargs:
312                lprint("Warning: unrecognized arg %s" % arg)
313
314    def __str__(self):
315        if hasattr(self, "opcode"):
316            opcodes_str = ["0x%02X" % x for x in self.opcode]
317        elif hasattr(self, "opcode1") and hasattr(self, "opcode2"):
318            opcodes_str = ["0x%02X" % x for x in self.opcode1]
319            opcodes_str.extend("0x%02X" % x for x in self.opcode2)
320        # Ensure opcodes initializer string is 3 long
321        opcodes_str.extend(["0", "0", "0"])
322        opcodes_str = "{" + ', '.join(opcodes_str[0:3]) + "}"
323
324        cpus_str = "|".join("CPU_%s" % x for x in sorted(self.cpu))
325
326        if len(self.modifiers) > 3:
327            raise ValueError("too many modifiers: %s" % (self.modifiers,))
328
329        cpus_str = []
330        if self.cpu is not None:
331            if len(self.cpu) > 3:
332                raise ValueError("too many CPUs: %s" % (self.cpu,))
333
334            # Ensure CPUs initializer string is at least 3 long
335            cpus_str.extend("CPU_%s" % x for x in sorted(self.cpu))
336
337        # Ensure cpus initializer string is 3 long; 0=CPU_Any
338        cpus_str.extend(["0", "0", "0"])
339
340
341        mods = ["MOD_%s" % x for x in self.modifiers]
342        # Ensure mods initializer string is 3 long
343        mods.extend(["0", "0", "0"])
344        mod_str = "{" + ', '.join(mods[0:3]) + "}"
345
346        gas_flags = []
347        if self.gas_only:
348            gas_flags.append("GAS_ONLY")
349        if self.gas_illegal:
350            gas_flags.append("GAS_ILLEGAL")
351        if self.gas_no_rev:
352            gas_flags.append("GAS_NO_REV")
353        if self.suffixes:
354            gas_flags.extend("SUF_%s" % x for x in sorted(self.suffixes))
355        gas_flags = "|".join(gas_flags)
356
357        # Build instruction info structure initializer
358        return "{ "+ ", ".join([gas_flags or "0",
359                                "|".join(self.misc_flags) or "0",
360                                cpus_str[0],
361                                cpus_str[1],
362                                cpus_str[2],
363                                mod_str,
364                                "%d" % (self.opersize or 0),
365                                "%d" % (self.def_opersize_64 or 0),
366                                self.special_prefix or "0",
367                                "%d" % self.opcode_len,
368                                opcodes_str,
369                                "%d" % (self.spare or 0),
370                                "%d" % len(self.operands),
371                                "%d" % self.all_operands_index]) + " }"
372
373groups = {}
374groupnames_ordered = []
375def add_group(name, **kwargs):
376    forms = groups.setdefault(name, [])
377    forms.append(GroupForm(**kwargs))
378    groupnames_ordered.append(name)
379
380class Insn(object):
381    def __init__(self, groupname, suffix=None, parser=None, modifiers=None,
382                 cpu=None, misc_flags=None, only64=False, not64=False,
383                 avx=False):
384        self.groupname = groupname
385        if suffix is None:
386            self.suffix = None
387        else:
388            self.suffix = suffix.upper()
389
390        self.parsers = None
391        if suffix is not None:
392            self.parsers = set(["gas"])
393        if parser is not None:
394            self.parsers = set([parser])
395
396        if modifiers is None:
397            self.modifiers = []
398        else:
399            self.modifiers = modifiers
400        if cpu is None:
401            self.cpu = None
402        else:
403            self.cpu = set(cpu)
404
405        if misc_flags is None:
406            self.misc_flags = None
407        else:
408            self.misc_flags = set([x for x in misc_flags])
409
410        if only64:
411            if self.misc_flags is None:
412                self.misc_flags = set()
413            self.misc_flags.add("ONLY_64")
414        if not64:
415            if self.misc_flags is None:
416                self.misc_flags = set()
417            self.misc_flags.add("NOT_64")
418        if avx:
419            if self.misc_flags is None:
420                self.misc_flags = set()
421            self.misc_flags.add("ONLY_AVX")
422            if self.cpu is None:
423                self.cpu = set(["AVX"])
424
425    def auto_cpu(self, parser):
426        """Determine lowest common denominator CPU from group and suffix.
427        Does nothing if CPU is already set."""
428        if self.cpu is not None:
429            return
430        # Scan through group, matching parser and suffix
431        for form in groups[self.groupname]:
432            if parser not in form.parsers:
433                continue
434            if (self.suffix is not None and len(self.suffix) == 1 and
435                (form.suffixes is None or self.suffix not in form.suffixes)):
436                continue
437            if self.cpu is None:
438                self.cpu = set(form.cpu)
439            else:
440                self.cpu = cpu_lcd(self.cpu, form.cpu)
441
442    def auto_misc_flags(self, parser):
443        """Determine lowest common denominator flags from group and suffix.
444        Does nothing if flags is already set."""
445        if self.misc_flags is not None:
446            return
447        # Scan through group, matching parser and suffix
448        for form in groups[self.groupname]:
449            if parser not in form.parsers:
450                continue
451            if (self.suffix is not None and len(self.suffix) == 1 and
452                (form.suffixes is None or self.suffix not in form.suffixes)):
453                continue
454            if self.misc_flags is None:
455                self.misc_flags = set(form.misc_flags)
456            else:
457                self.misc_flags &= form.misc_flags
458
459    def copy(self):
460        """Return a shallow copy."""
461        return Insn(self.groupname,
462                    suffix=self.suffix,
463                    modifiers=self.modifiers,
464                    cpu=self.cpu,
465                    misc_flags=self.misc_flags)
466
467    def __str__(self):
468        if self.suffix is None:
469            suffix_str = "SUF_Z"
470        elif len(self.suffix) == 1:
471            suffix_str = "SUF_" + self.suffix
472        else:
473            suffix_str = self.suffix
474
475        cpus_str = []
476        if self.cpu is not None:
477            if len(self.cpu) > 3:
478                raise ValueError("too many CPUs: %s" % (self.cpu,))
479            cpus_str.extend("CPU_%s" % x for x in sorted(self.cpu))
480
481        # Ensure cpus initializer string is 3 long
482        cpus_str.extend(["0", "0", "0"])
483
484        if len(self.modifiers) > 3:
485            raise ValueError("too many modifiers")
486        mods_str = ["0x%02X" % x for x in self.modifiers]
487
488        # Ensure modifiers is at least 3 long
489        mods_str.extend(["0", "0", "0"])
490
491        return ",\t".join(["%s_insn" % self.groupname,
492                           "%d" % len(groups[self.groupname]),
493                           suffix_str,
494                           mods_str[0],
495                           mods_str[1],
496                           mods_str[2],
497                           "|".join(self.misc_flags or []) or "0",
498                           cpus_str[0],
499                           cpus_str[1],
500                           cpus_str[2]])
501
502insns = {}
503def add_insn(name, groupname, **kwargs):
504    opts = insns.setdefault(name, [])
505    opts.append(Insn(groupname, **kwargs))
506
507class Prefix(object):
508    def __init__(self, groupname, value, only64=False):
509        self.groupname = groupname
510        self.value = value
511        self.only64 = only64
512
513    def __str__(self):
514        return ",\t".join(["NULL",
515                           "X86_%s>>8" % self.groupname,
516                           "0x%02X" % self.value,
517                           "0",
518                           "0",
519                           "0",
520                           self.only64 and "ONLY_64" or "0",
521                           "0",
522                           "0",
523                           "0"])
524
525gas_insns = {}
526nasm_insns = {}
527
528def add_prefix(name, groupname, value, parser=None, **kwargs):
529    prefix = Prefix(groupname, value, **kwargs)
530    if parser is None or parser == "gas":
531        gas_insns[name] = prefix
532    if parser is None or parser == "nasm":
533        nasm_insns[name] = prefix
534
535def finalize_insns():
536    unused_groups = set(groups.keys())
537    for name in insns:
538        for insn in insns[name]:
539            group = groups[insn.groupname]
540            unused_groups.discard(insn.groupname)
541
542            parsers = set()
543            for form in group:
544                parsers |= form.parsers
545            if insn.parsers is not None:
546                parsers &= insn.parsers
547
548            if "gas" in parsers:
549                suffixes = set()
550                if insn.suffix is None:
551                    for form in group:
552                        if form.gen_suffix and form.suffixes is not None:
553                            suffixes |= form.suffixes
554
555                if not suffixes:
556                    suffixes.add("Z")
557                for suffix in suffixes:
558                    if suffix == "Z":
559                        keyword = name
560                    else:
561                        keyword = name+suffix
562                    keyword = keyword.lower()
563                    if keyword in gas_insns:
564                        raise ValueError("duplicate gas instruction %s" %
565                                         keyword)
566                    newinsn = insn.copy()
567                    if insn.suffix is None:
568                        newinsn.suffix = suffix
569                    newinsn.auto_cpu("gas")
570                    newinsn.auto_misc_flags("gas")
571                    gas_insns[keyword] = newinsn
572
573            if "nasm" in parsers:
574                keyword = name
575                if keyword in nasm_insns:
576                    raise ValueError("duplicate nasm instruction %s" % keyword)
577                newinsn = insn.copy()
578                newinsn.auto_cpu("nasm")
579                newinsn.auto_misc_flags("nasm")
580                nasm_insns[keyword] = newinsn
581
582    unused_groups.discard("empty")
583    unused_groups.discard("not64")
584    if unused_groups:
585        lprint("warning: unused groups: %s" % ", ".join(unused_groups))
586
587def output_insns(f, parser, insns):
588    lprint("/* Generated by %s r%s, do not edit */" % \
589        (scriptname, scriptrev), f)
590    lprint("""%%ignore-case
591%%language=ANSI-C
592%%compare-strncmp
593%%readonly-tables
594%%enum
595%%struct-type
596%%define hash-function-name insnprefix_%s_hash
597%%define lookup-function-name insnprefix_%s_find
598struct insnprefix_parse_data;
599%%%%""" % (parser, parser), f)
600    for keyword in sorted(insns):
601        lprint("%s,\t%s" % (keyword.lower(), insns[keyword]), f)
602
603def output_gas_insns(f):
604    output_insns(f, "gas", gas_insns)
605
606def output_nasm_insns(f):
607    output_insns(f, "nasm", nasm_insns)
608
609def output_groups(f):
610    # Merge all operand lists into single list
611    # Sort by number of operands to shorten output
612    all_operands = []
613    if version_info[0] == 2:
614        gi = groups.itervalues()
615    else:
616        gi = groups.values()
617    for form in sorted((form for g in gi for form in g),
618                       key=lambda x:len(x.operands), reverse=True):
619        num_operands = len(form.operands)
620        for i in range(len(all_operands)):
621            if all_operands[i:i+num_operands] == form.operands:
622                form.all_operands_index = i
623                break
624        else:
625            form.all_operands_index = len(all_operands)
626            all_operands.extend(form.operands)
627
628    # Output operands list
629    lprint("/* Generated by %s r%s, do not edit */" % \
630        (scriptname, scriptrev), f)
631    lprint("static const x86_info_operand insn_operands[] = {", f)
632    lprint("   ", f, '')
633    lprint(",\n    ".join(str(x) for x in all_operands), f)
634    lprint("};\n", f)
635
636    # Output groups
637    seen = set()
638    for name in groupnames_ordered:
639        if name in seen:
640            continue
641        seen.add(name)
642        lprint("static const x86_insn_info %s_insn[] = {" % name, f)
643        lprint("   ", f, '')
644        lprint(",\n    ".join(str(x) for x in groups[name]), f)
645        lprint("};\n", f)
646
647#####################################################################
648# General instruction groupings
649#####################################################################
650
651#
652# Empty instruction
653#
654add_group("empty", opcode=[], operands=[])
655
656#
657# Placeholder for instructions invalid in 64-bit mode
658#
659add_group("not64", opcode=[], operands=[], not64=True)
660
661#
662# One byte opcode instructions with no operands
663#
664add_group("onebyte",
665    modifiers=["Op0Add", "OpSizeR", "DOpS64R"],
666    opcode=[0x00],
667    operands=[])
668
669#
670# One byte opcode instructions with "special" prefix with no operands
671#
672add_group("onebyte_prefix",
673    modifiers=["PreAdd", "Op0Add"],
674    prefix=0x00,
675    opcode=[0x00],
676    operands=[])
677
678#
679# Two byte opcode instructions with no operands
680#
681add_group("twobyte",
682    gen_suffix=False,
683    suffixes=["l", "q"],
684    modifiers=["Op0Add", "Op1Add"],
685    opcode=[0x00, 0x00],
686    operands=[])
687
688#
689# Three byte opcode instructions with no operands
690#
691add_group("threebyte",
692    modifiers=["Op0Add", "Op1Add", "Op2Add"],
693    opcode=[0x00, 0x00, 0x00],
694    operands=[])
695
696#
697# One byte opcode instructions with general memory operand
698#
699add_group("onebytemem",
700    gen_suffix=False,
701    suffixes=["l", "q", "s"],
702    modifiers=["SpAdd", "Op0Add"],
703    opcode=[0x00],
704    spare=0,
705    operands=[Operand(type="Mem", dest="EA")])
706
707#
708# Two byte opcode instructions with general memory operand
709#
710add_group("twobytemem",
711    gen_suffix=False,
712    suffixes=["w", "l", "q", "s"],
713    modifiers=["SpAdd", "Op0Add", "Op1Add"],
714    opcode=[0x00, 0x00],
715    spare=0,
716    operands=[Operand(type="Mem", relaxed=True, dest="EA")])
717
718#
719# mov
720#
721
722# Absolute forms for non-64-bit mode
723for sfx, sz in zip("bwl", [8, 16, 32]):
724    add_group("mov",
725        suffix=sfx,
726        not64=True,
727        opersize=sz,
728        opcode=[0xA0+(sz!=8)],
729        operands=[Operand(type="Areg", size=sz, dest=None),
730                  Operand(type="MemOffs", size=sz, relaxed=True, dest="EA")])
731
732for sfx, sz in zip("bwl", [8, 16, 32]):
733    add_group("mov",
734        suffix=sfx,
735        not64=True,
736        opersize=sz,
737        opcode=[0xA2+(sz!=8)],
738        operands=[Operand(type="MemOffs", size=sz, relaxed=True, dest="EA"),
739                  Operand(type="Areg", size=sz, dest=None)])
740
741# 64-bit absolute forms for 64-bit mode.  Disabled for GAS, see movabs
742for sz in (8, 16, 32, 64):
743    add_group("mov",
744        opersize=sz,
745        opcode=[0xA0+(sz!=8)],
746        only64=True,
747        operands=[Operand(type="Areg", size=sz, dest=None),
748                  Operand(type="MemOffs", size=sz, relaxed=True, dest="EA64")])
749
750for sz in (8, 16, 32, 64):
751    add_group("mov",
752        only64=True,
753        opersize=sz,
754        opcode=[0xA2+(sz!=8)],
755        operands=[Operand(type="MemOffs", size=sz, relaxed=True, dest="EA64"),
756                  Operand(type="Areg", size=sz, dest=None)])
757
758# General 32-bit forms using Areg / short absolute option
759for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
760    add_group("mov",
761        suffix=sfx,
762        opersize=sz,
763        opcode1=[0x88+(sz!=8)],
764        opcode2=[0xA2+(sz!=8)],
765        operands=[
766            Operand(type="RM", size=sz, relaxed=True, dest="EA", opt="ShortMov"),
767            Operand(type="Areg", size=sz, dest="Spare")])
768
769# General 32-bit forms
770for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
771    add_group("mov",
772        suffix=sfx,
773        opersize=sz,
774        opcode=[0x88+(sz!=8)],
775        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
776                  Operand(type="Reg", size=sz, dest="Spare")])
777
778# General 32-bit forms using Areg / short absolute option
779for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
780    add_group("mov",
781        suffix=sfx,
782        opersize=sz,
783        opcode1=[0x8A+(sz!=8)],
784        opcode2=[0xA0+(sz!=8)],
785        operands=[Operand(type="Areg", size=sz, dest="Spare"),
786                  Operand(type="RM", size=sz, relaxed=True, dest="EA",
787                          opt="ShortMov")])
788
789# General 32-bit forms
790for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
791    add_group("mov",
792        suffix=sfx,
793        opersize=sz,
794        opcode=[0x8A+(sz!=8)],
795        operands=[Operand(type="Reg", size=sz, dest="Spare"),
796                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
797
798# Segment register forms
799add_group("mov",
800    suffix="w",
801    opcode=[0x8C],
802    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA"),
803              Operand(type="SegReg", size=16, relaxed=True, dest="Spare")])
804for sfx, sz in zip("wlq", [16, 32, 64]):
805    add_group("mov",
806        suffix=sfx,
807        opersize=sz,
808        opcode=[0x8C],
809        operands=[
810            Operand(type="Reg", size=sz, dest="EA"),
811            Operand(type="SegReg", size=16, relaxed=True, dest="Spare")])
812add_group("mov",
813    suffix="w",
814    opcode=[0x8E],
815    operands=[Operand(type="SegReg", size=16, relaxed=True, dest="Spare"),
816              Operand(type="RM", size=16, relaxed=True, dest="EA")])
817for sfx, sz in zip("lq", [32, 64]):
818    add_group("mov",
819        suffix=sfx,
820        opcode=[0x8E],
821        operands=[
822            Operand(type="SegReg", size=16, relaxed=True, dest="Spare"),
823            Operand(type="Reg", size=sz, dest="EA")])
824
825# Immediate forms
826add_group("mov",
827    suffix="b",
828    opcode=[0xB0],
829    operands=[Operand(type="Reg", size=8, dest="Op0Add"),
830              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
831for sfx, sz in zip("wl", [16, 32]):
832    add_group("mov",
833        suffix=sfx,
834        opersize=sz,
835        opcode=[0xB8],
836        operands=[Operand(type="Reg", size=sz, dest="Op0Add"),
837                  Operand(type="Imm", size=sz, relaxed=True, dest="Imm")])
838# 64-bit forced size form
839add_group("mov",
840    parsers=["nasm"],
841    opersize=64,
842    opcode=[0xB8],
843    operands=[Operand(type="Reg", size=64, dest="Op0Add"),
844              Operand(type="Imm", size=64, dest="Imm")])
845add_group("mov",
846    suffix="q",
847    opersize=64,
848    opcode1=[0xB8],
849    opcode2=[0xC7],
850    operands=[Operand(type="Reg", size=64, dest="Op0Add"),
851              Operand(type="Imm", size=64, relaxed=True, dest="Imm",
852                      opt="SImm32Avail")])
853# Need two sets here, one for strictness on left side, one for right.
854for sfx, sz, immsz in zip("bwlq", [8, 16, 32, 64], [8, 16, 32, 32]):
855    add_group("mov",
856        suffix=sfx,
857        opersize=sz,
858        opcode=[0xC6+(sz!=8)],
859        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
860                  Operand(type="Imm", size=immsz, dest="Imm")])
861for sfx, sz, immsz in zip("bwlq", [8, 16, 32, 64], [8, 16, 32, 32]):
862    add_group("mov",
863            suffix=sfx,
864            opersize=sz,
865            opcode=[0xC6+(sz!=8)],
866            operands=[Operand(type="RM", size=sz, dest="EA"),
867                Operand(type="Imm", size=immsz, relaxed=True, dest="Imm")])
868
869# CR forms
870add_group("mov",
871    suffix="l",
872    not64=True,
873    cpu=["Priv"],
874    opcode=[0x0F, 0x22],
875    operands=[Operand(type="CR4", size=32, dest="Spare"),
876              Operand(type="Reg", size=32, dest="EA")])
877add_group("mov",
878    suffix="l",
879    not64=True,
880    cpu=["Priv"],
881    opcode=[0x0F, 0x22],
882    operands=[Operand(type="CRReg", size=32, dest="Spare"),
883              Operand(type="Reg", size=32, dest="EA")])
884add_group("mov",
885    suffix="q",
886    cpu=["Priv"],
887    opcode=[0x0F, 0x22],
888    operands=[Operand(type="CRReg", size=32, dest="Spare"),
889              Operand(type="Reg", size=64, dest="EA")])
890add_group("mov",
891    suffix="l",
892    not64=True,
893    cpu=["Priv"],
894    opcode=[0x0F, 0x20],
895    operands=[Operand(type="Reg", size=32, dest="EA"),
896              Operand(type="CR4", size=32, dest="Spare")])
897add_group("mov",
898    suffix="l",
899    cpu=["Priv"],
900    not64=True,
901    opcode=[0x0F, 0x20],
902    operands=[Operand(type="Reg", size=32, dest="EA"),
903              Operand(type="CRReg", size=32, dest="Spare")])
904add_group("mov",
905    suffix="q",
906    cpu=["Priv"],
907    opcode=[0x0F, 0x20],
908    operands=[Operand(type="Reg", size=64, dest="EA"),
909              Operand(type="CRReg", size=32, dest="Spare")])
910
911# DR forms
912add_group("mov",
913    suffix="l",
914    not64=True,
915    cpu=["Priv"],
916    opcode=[0x0F, 0x23],
917    operands=[Operand(type="DRReg", size=32, dest="Spare"),
918              Operand(type="Reg", size=32, dest="EA")])
919add_group("mov",
920    suffix="q",
921    cpu=["Priv"],
922    opcode=[0x0F, 0x23],
923    operands=[Operand(type="DRReg", size=32, dest="Spare"),
924              Operand(type="Reg", size=64, dest="EA")])
925add_group("mov",
926    suffix="l",
927    not64=True,
928    cpu=["Priv"],
929    opcode=[0x0F, 0x21],
930    operands=[Operand(type="Reg", size=32, dest="EA"),
931              Operand(type="DRReg", size=32, dest="Spare")])
932add_group("mov",
933    suffix="q",
934    cpu=["Priv"],
935    opcode=[0x0F, 0x21],
936    operands=[Operand(type="Reg", size=64, dest="EA"),
937              Operand(type="DRReg", size=32, dest="Spare")])
938
939# MMX forms for GAS parser (copied from movq)
940add_group("mov",
941    suffix="q",
942    cpu=["MMX"],
943    parsers=["gas"],
944    opcode=[0x0F, 0x6F],
945    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
946              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
947add_group("mov",
948    suffix="q",
949    cpu=["MMX"],
950    parsers=["gas"],
951    opersize=64,
952    opcode=[0x0F, 0x6E],
953    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
954              Operand(type="RM", size=64, relaxed=True, dest="EA")])
955add_group("mov",
956    suffix="q",
957    cpu=["MMX"],
958    parsers=["gas"],
959    opcode=[0x0F, 0x7F],
960    operands=[Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
961              Operand(type="SIMDReg", size=64, dest="Spare")])
962add_group("mov",
963    suffix="q",
964    cpu=["MMX"],
965    parsers=["gas"],
966    opersize=64,
967    opcode=[0x0F, 0x7E],
968    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
969              Operand(type="SIMDReg", size=64, dest="Spare")])
970
971# SSE2 forms for GAS parser (copied from movq)
972add_group("mov",
973    suffix="q",
974    cpu=["SSE2"],
975    parsers=["gas"],
976    prefix=0xF3,
977    opcode=[0x0F, 0x7E],
978    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
979              Operand(type="SIMDReg", size=128, dest="EA")])
980add_group("mov",
981    suffix="q",
982    cpu=["SSE2"],
983    parsers=["gas"],
984    prefix=0xF3,
985    opcode=[0x0F, 0x7E],
986    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
987              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
988add_group("mov",
989    suffix="q",
990    cpu=["SSE2"],
991    parsers=["gas"],
992    opersize=64,
993    prefix=0x66,
994    opcode=[0x0F, 0x6E],
995    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
996              Operand(type="RM", size=64, relaxed=True, dest="EA")])
997add_group("mov",
998    suffix="q",
999    cpu=["SSE2"],
1000    parsers=["gas"],
1001    prefix=0x66,
1002    opcode=[0x0F, 0xD6],
1003    operands=[Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
1004              Operand(type="SIMDReg", size=128, dest="Spare")])
1005add_group("mov",
1006    suffix="q",
1007    cpu=["SSE2"],
1008    parsers=["gas"],
1009    opersize=64,
1010    prefix=0x66,
1011    opcode=[0x0F, 0x7E],
1012    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
1013              Operand(type="SIMDReg", size=128, dest="Spare")])
1014
1015add_insn("mov", "mov")
1016
1017#
1018# 64-bit absolute move (for GAS).
1019# These are disabled for GAS for normal mov above.
1020#
1021add_group("movabs",
1022    suffix="b",
1023    only64=True,
1024    opcode=[0xA0],
1025    operands=[Operand(type="Areg", size=8, dest=None),
1026              Operand(type="MemOffs", size=8, relaxed=True, dest="EA64")])
1027for sfx, sz in zip("wlq", [16, 32, 64]):
1028    add_group("movabs",
1029        only64=True,
1030        suffix=sfx,
1031        opersize=sz,
1032        opcode=[0xA1],
1033        operands=[Operand(type="Areg", size=sz, dest=None),
1034                  Operand(type="MemOffs", size=sz, relaxed=True,
1035                          dest="EA64")])
1036
1037add_group("movabs",
1038    suffix="b",
1039    only64=True,
1040    opcode=[0xA2],
1041    operands=[Operand(type="MemOffs", size=8, relaxed=True, dest="EA64"),
1042              Operand(type="Areg", size=8, dest=None)])
1043for sfx, sz in zip("wlq", [16, 32, 64]):
1044    add_group("movabs",
1045        suffix=sfx,
1046        only64=True,
1047        opersize=sz,
1048        opcode=[0xA3],
1049        operands=[Operand(type="MemOffs", size=sz, relaxed=True,
1050                          dest="EA64"),
1051                  Operand(type="Areg", size=sz, dest=None)])
1052
1053# 64-bit immediate form
1054add_group("movabs",
1055    suffix="q",
1056    opersize=64,
1057    opcode=[0xB8],
1058    operands=[Operand(type="Reg", size=64, dest="Op0Add"),
1059              Operand(type="Imm", size=64, relaxed=True, dest="Imm")])
1060
1061add_insn("movabs", "movabs", parser="gas")
1062
1063#
1064# Move with sign/zero extend
1065#
1066add_group("movszx",
1067    suffix="b",
1068    cpu=["386"],
1069    modifiers=["Op1Add"],
1070    opersize=16,
1071    opcode=[0x0F, 0x00],
1072    operands=[Operand(type="Reg", size=16, dest="Spare"),
1073              Operand(type="RM", size=8, relaxed=True, dest="EA")])
1074add_group("movszx",
1075    suffix="b",
1076    cpu=["386"],
1077    modifiers=["Op1Add"],
1078    opersize=32,
1079    opcode=[0x0F, 0x00],
1080    operands=[Operand(type="Reg", size=32, dest="Spare"),
1081              Operand(type="RM", size=8, dest="EA")])
1082add_group("movszx",
1083    suffix="b",
1084    modifiers=["Op1Add"],
1085    opersize=64,
1086    opcode=[0x0F, 0x00],
1087    operands=[Operand(type="Reg", size=64, dest="Spare"),
1088              Operand(type="RM", size=8, dest="EA")])
1089add_group("movszx",
1090    suffix="w",
1091    cpu=["386"],
1092    modifiers=["Op1Add"],
1093    opersize=32,
1094    opcode=[0x0F, 0x01],
1095    operands=[Operand(type="Reg", size=32, dest="Spare"),
1096              Operand(type="RM", size=16, dest="EA")])
1097add_group("movszx",
1098    suffix="w",
1099    modifiers=["Op1Add"],
1100    opersize=64,
1101    opcode=[0x0F, 0x01],
1102    operands=[Operand(type="Reg", size=64, dest="Spare"),
1103              Operand(type="RM", size=16, dest="EA")])
1104
1105add_insn("movsbw", "movszx", suffix="b", modifiers=[0xBE])
1106add_insn("movsbl", "movszx", suffix="b", modifiers=[0xBE])
1107add_insn("movswl", "movszx", suffix="w", modifiers=[0xBE])
1108add_insn("movsbq", "movszx", suffix="b", modifiers=[0xBE], only64=True)
1109add_insn("movswq", "movszx", suffix="w", modifiers=[0xBE], only64=True)
1110add_insn("movsx", "movszx", modifiers=[0xBE])
1111add_insn("movzbw", "movszx", suffix="b", modifiers=[0xB6])
1112add_insn("movzbl", "movszx", suffix="b", modifiers=[0xB6])
1113add_insn("movzwl", "movszx", suffix="w", modifiers=[0xB6])
1114add_insn("movzbq", "movszx", suffix="b", modifiers=[0xB6], only64=True)
1115add_insn("movzwq", "movszx", suffix="w", modifiers=[0xB6], only64=True)
1116add_insn("movzx", "movszx", modifiers=[0xB6])
1117
1118#
1119# Move with sign-extend doubleword (64-bit mode only)
1120#
1121add_group("movsxd",
1122    suffix="l",
1123    opersize=64,
1124    opcode=[0x63],
1125    operands=[Operand(type="Reg", size=64, dest="Spare"),
1126              Operand(type="RM", size=32, dest="EA")])
1127
1128add_insn("movslq", "movsxd", suffix="l")
1129add_insn("movsxd", "movsxd", parser="nasm")
1130
1131#
1132# Push instructions
1133#
1134add_group("push",
1135    def_opersize_64=64,
1136    opcode=[0x50],
1137    operands=[Operand(type="Reg", size="BITS", dest="Op0Add")])
1138add_group("push",
1139    suffix="w",
1140    opersize=16,
1141    def_opersize_64=64,
1142    opcode=[0x50],
1143    operands=[Operand(type="Reg", size=16, dest="Op0Add")])
1144add_group("push",
1145    suffix="l",
1146    not64=True,
1147    opersize=32,
1148    opcode=[0x50],
1149    operands=[Operand(type="Reg", size=32, dest="Op0Add")])
1150add_group("push",
1151    suffix="q",
1152    only64=True,
1153    def_opersize_64=64,
1154    opcode=[0x50],
1155    operands=[Operand(type="Reg", size=64, dest="Op0Add")])
1156
1157add_group("push",
1158    def_opersize_64=64,
1159    opcode=[0xFF],
1160    spare=6,
1161    operands=[Operand(type="RM", size="BITS", dest="EA")])
1162add_group("push",
1163    suffix="w",
1164    opersize=16,
1165    def_opersize_64=64,
1166    opcode=[0xFF],
1167    spare=6,
1168    operands=[Operand(type="RM", size=16, dest="EA")])
1169add_group("push",
1170    suffix="l",
1171    not64=True,
1172    opersize=32,
1173    opcode=[0xFF],
1174    spare=6,
1175    operands=[Operand(type="RM", size=32, dest="EA")])
1176add_group("push",
1177    suffix="q",
1178    only64=True,
1179    def_opersize_64=64,
1180    opcode=[0xFF],
1181    spare=6,
1182    operands=[Operand(type="RM", size=64, dest="EA")])
1183
1184add_group("push",
1185    cpu=["186"],
1186    parsers=["nasm"],
1187    def_opersize_64=64,
1188    opcode=[0x6A],
1189    operands=[Operand(type="Imm", size=8, dest="SImm")])
1190add_group("push",
1191    cpu=["186"],
1192    parsers=["gas"],
1193    def_opersize_64=64,
1194    opcode=[0x6A],
1195    operands=[Operand(type="Imm", size=8, relaxed=True, dest="SImm")])
1196add_group("push",
1197    suffix="q",
1198    only64=True,
1199    opersize=64,
1200    def_opersize_64=64,
1201    opcode1=[0x6A],
1202    opcode2=[0x68],
1203    operands=[Operand(type="Imm", size=32, relaxed=True, dest="SImm",
1204                      opt="SImm8")])
1205add_group("push",
1206    not64=True,
1207    cpu=["186"],
1208    parsers=["nasm"],
1209    opcode1=[0x6A],
1210    opcode2=[0x68],
1211    operands=[Operand(type="Imm", size="BITS", relaxed=True, dest="Imm",
1212                      opt="SImm8")])
1213add_group("push",
1214    suffix="w",
1215    cpu=["186"],
1216    opersize=16,
1217    def_opersize_64=64,
1218    opcode1=[0x6A],
1219    opcode2=[0x68],
1220    operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm",
1221                      opt="SImm8")])
1222add_group("push",
1223    suffix="l",
1224    not64=True,
1225    opersize=32,
1226    opcode1=[0x6A],
1227    opcode2=[0x68],
1228    operands=[Operand(type="Imm", size=32, relaxed=True, dest="Imm",
1229                      opt="SImm8")])
1230# Need these when we don't match the BITS size, but they need to be
1231# below the above line so the optimizer can kick in by default.
1232add_group("push",
1233    cpu=["186"],
1234    parsers=["nasm"],
1235    opersize=16,
1236    def_opersize_64=64,
1237    opcode=[0x68],
1238    operands=[Operand(type="Imm", size=16, dest="Imm")])
1239add_group("push",
1240    not64=True,
1241    parsers=["nasm"],
1242    opersize=32,
1243    opcode=[0x68],
1244    operands=[Operand(type="Imm", size=32, dest="Imm")])
1245add_group("push",
1246    only64=True,
1247    parsers=["nasm"],
1248    opersize=64,
1249    def_opersize_64=64,
1250    opcode=[0x68],
1251    operands=[Operand(type="Imm", size=32, dest="SImm")])
1252add_group("push",
1253    not64=True,
1254    opcode=[0x0E],
1255    operands=[Operand(type="CS", dest=None)])
1256add_group("push",
1257    suffix="w",
1258    not64=True,
1259    opersize=16,
1260    opcode=[0x0E],
1261    operands=[Operand(type="CS", size=16, dest=None)])
1262add_group("push",
1263    suffix="l",
1264    not64=True,
1265    opersize=32,
1266    opcode=[0x0E],
1267    operands=[Operand(type="CS", size=32, dest=None)])
1268add_group("push",
1269    not64=True,
1270    opcode=[0x16],
1271    operands=[Operand(type="SS", dest=None)])
1272add_group("push",
1273    suffix="w",
1274    not64=True,
1275    opersize=16,
1276    opcode=[0x16],
1277    operands=[Operand(type="SS", size=16, dest=None)])
1278add_group("push",
1279    suffix="l",
1280    not64=True,
1281    opersize=32,
1282    opcode=[0x16],
1283    operands=[Operand(type="SS", size=32, dest=None)])
1284add_group("push",
1285    not64=True,
1286    opcode=[0x1E],
1287    operands=[Operand(type="DS", dest=None)])
1288add_group("push",
1289    suffix="w",
1290    not64=True,
1291    opersize=16,
1292    opcode=[0x1E],
1293    operands=[Operand(type="DS", size=16, dest=None)])
1294add_group("push",
1295    suffix="l",
1296    not64=True,
1297    opersize=32,
1298    opcode=[0x1E],
1299    operands=[Operand(type="DS", size=32, dest=None)])
1300add_group("push",
1301    not64=True,
1302    opcode=[0x06],
1303    operands=[Operand(type="ES", dest=None)])
1304add_group("push",
1305    suffix="w",
1306    not64=True,
1307    opersize=16,
1308    opcode=[0x06],
1309    operands=[Operand(type="ES", size=16, dest=None)])
1310add_group("push",
1311    suffix="l",
1312    not64=True,
1313    opersize=32,
1314    opcode=[0x06],
1315    operands=[Operand(type="ES", size=32, dest=None)])
1316add_group("push",
1317    opcode=[0x0F, 0xA0],
1318    operands=[Operand(type="FS", dest=None)])
1319add_group("push",
1320    suffix="w",
1321    opersize=16,
1322    opcode=[0x0F, 0xA0],
1323    operands=[Operand(type="FS", size=16, dest=None)])
1324add_group("push",
1325    suffix="l",
1326    opersize=32,
1327    opcode=[0x0F, 0xA0],
1328    operands=[Operand(type="FS", size=32, dest=None)])
1329add_group("push",
1330    opcode=[0x0F, 0xA8],
1331    operands=[Operand(type="GS", dest=None)])
1332add_group("push",
1333    suffix="w",
1334    opersize=16,
1335    opcode=[0x0F, 0xA8],
1336    operands=[Operand(type="GS", size=16, dest=None)])
1337add_group("push",
1338    suffix="l",
1339    opersize=32,
1340    opcode=[0x0F, 0xA8],
1341    operands=[Operand(type="GS", size=32, dest=None)])
1342
1343add_insn("push", "push")
1344add_insn("pusha", "onebyte", modifiers=[0x60, 0], cpu=["186"], not64=True)
1345add_insn("pushad", "onebyte", parser="nasm", modifiers=[0x60, 32],
1346         cpu=["386"], not64=True)
1347add_insn("pushal", "onebyte", parser="gas", modifiers=[0x60, 32],
1348         cpu=["386"], not64=True)
1349add_insn("pushaw", "onebyte", modifiers=[0x60, 16], cpu=["186"], not64=True)
1350
1351#
1352# Pop instructions
1353#
1354add_group("pop",
1355    def_opersize_64=64,
1356    opcode=[0x58],
1357    operands=[Operand(type="Reg", size="BITS", dest="Op0Add")])
1358add_group("pop",
1359    suffix="w",
1360    opersize=16,
1361    def_opersize_64=64,
1362    opcode=[0x58],
1363    operands=[Operand(type="Reg", size=16, dest="Op0Add")])
1364add_group("pop",
1365    suffix="l",
1366    not64=True,
1367    opersize=32,
1368    opcode=[0x58],
1369    operands=[Operand(type="Reg", size=32, dest="Op0Add")])
1370add_group("pop",
1371    suffix="q",
1372    only64=True,
1373    def_opersize_64=64,
1374    opcode=[0x58],
1375    operands=[Operand(type="Reg", size=64, dest="Op0Add")])
1376
1377add_group("pop",
1378    def_opersize_64=64,
1379    opcode=[0x8F],
1380    operands=[Operand(type="RM", size="BITS", dest="EA")])
1381add_group("pop",
1382    suffix="w",
1383    opersize=16,
1384    def_opersize_64=64,
1385    opcode=[0x8F],
1386    operands=[Operand(type="RM", size=16, dest="EA")])
1387add_group("pop",
1388    suffix="l",
1389    not64=True,
1390    opersize=32,
1391    opcode=[0x8F],
1392    operands=[Operand(type="RM", size=32, dest="EA")])
1393add_group("pop",
1394    suffix="q",
1395    only64=True,
1396    def_opersize_64=64,
1397    opcode=[0x8F],
1398    operands=[Operand(type="RM", size=64, dest="EA")])
1399
1400# POP CS is debateably valid on the 8086, if obsolete and undocumented.
1401# We don't include it because it's VERY unlikely it will ever be used
1402# anywhere.  If someone really wants it they can db 0x0F it.
1403#add_group("pop",
1404#    cpu=["Undoc", "Obs"],
1405#    opcode=[0x0F],
1406#    operands=[Operand(type="CS", dest=None)])
1407add_group("pop",
1408    not64=True,
1409    opcode=[0x17],
1410    operands=[Operand(type="SS", dest=None)])
1411add_group("pop",
1412    not64=True,
1413    opersize=16,
1414    opcode=[0x17],
1415    operands=[Operand(type="SS", size=16, dest=None)])
1416add_group("pop",
1417    not64=True,
1418    opersize=32,
1419    opcode=[0x17],
1420    operands=[Operand(type="SS", size=32, dest=None)])
1421add_group("pop",
1422    not64=True,
1423    opcode=[0x1F],
1424    operands=[Operand(type="DS", dest=None)])
1425add_group("pop",
1426    not64=True,
1427    opersize=16,
1428    opcode=[0x1F],
1429    operands=[Operand(type="DS", size=16, dest=None)])
1430add_group("pop",
1431    not64=True,
1432    opersize=32,
1433    opcode=[0x1F],
1434    operands=[Operand(type="DS", size=32, dest=None)])
1435add_group("pop",
1436    not64=True,
1437    opcode=[0x07],
1438    operands=[Operand(type="ES", dest=None)])
1439add_group("pop",
1440    not64=True,
1441    opersize=16,
1442    opcode=[0x07],
1443    operands=[Operand(type="ES", size=16, dest=None)])
1444add_group("pop",
1445    not64=True,
1446    opersize=32,
1447    opcode=[0x07],
1448    operands=[Operand(type="ES", size=32, dest=None)])
1449add_group("pop",
1450    opcode=[0x0F, 0xA1],
1451    operands=[Operand(type="FS", dest=None)])
1452add_group("pop",
1453    opersize=16,
1454    opcode=[0x0F, 0xA1],
1455    operands=[Operand(type="FS", size=16, dest=None)])
1456add_group("pop",
1457    opersize=32,
1458    opcode=[0x0F, 0xA1],
1459    operands=[Operand(type="FS", size=32, dest=None)])
1460add_group("pop",
1461    opcode=[0x0F, 0xA9],
1462    operands=[Operand(type="GS", dest=None)])
1463add_group("pop",
1464    opersize=16,
1465    opcode=[0x0F, 0xA9],
1466    operands=[Operand(type="GS", size=16, dest=None)])
1467add_group("pop",
1468    opersize=32,
1469    opcode=[0x0F, 0xA9],
1470    operands=[Operand(type="GS", size=32, dest=None)])
1471
1472add_insn("pop", "pop")
1473add_insn("popa", "onebyte", modifiers=[0x61, 0], cpu=["186"], not64=True)
1474add_insn("popad", "onebyte", parser="nasm", modifiers=[0x61, 32],
1475         cpu=["386"], not64=True)
1476add_insn("popal", "onebyte", parser="gas", modifiers=[0x61, 32],
1477         cpu=["386"], not64=True)
1478add_insn("popaw", "onebyte", modifiers=[0x61, 16], cpu=["186"], not64=True)
1479
1480#
1481# Exchange instructions
1482#
1483add_group("xchg",
1484    suffix="b",
1485    opcode=[0x86],
1486    operands=[Operand(type="RM", size=8, relaxed=True, dest="EA"),
1487              Operand(type="Reg", size=8, dest="Spare")])
1488add_group("xchg",
1489    suffix="b",
1490    opcode=[0x86],
1491    operands=[Operand(type="Reg", size=8, dest="Spare"),
1492              Operand(type="RM", size=8, relaxed=True, dest="EA")])
1493# We could be extra-efficient in the 64-bit mode case here.
1494# XCHG AX, AX in 64-bit mode is a NOP, as it doesn't clear the
1495# high 48 bits of RAX. Thus we don't need the operand-size prefix.
1496# But this feels too clever, and probably not what the user really
1497# expects in the generated code, so we don't do it.
1498#add_group("xchg",
1499#    suffix="w",
1500#    only64=True,
1501#    opcode=[0x90],
1502#    operands=[Operand(type="Areg", size=16, dest=None),
1503#              Operand(type="AReg", size=16, dest="Op0Add")])
1504add_group("xchg",
1505    suffix="w",
1506    opersize=16,
1507    opcode=[0x90],
1508    operands=[Operand(type="Areg", size=16, dest=None),
1509              Operand(type="Reg", size=16, dest="Op0Add")])
1510add_group("xchg",
1511    suffix="w",
1512    opersize=16,
1513    opcode=[0x90],
1514    operands=[Operand(type="Reg", size=16, dest="Op0Add"),
1515              Operand(type="Areg", size=16, dest=None)])
1516add_group("xchg",
1517    suffix="w",
1518    opersize=16,
1519    opcode=[0x87],
1520    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA"),
1521              Operand(type="Reg", size=16, dest="Spare")])
1522add_group("xchg",
1523    suffix="w",
1524    opersize=16,
1525    opcode=[0x87],
1526    operands=[Operand(type="Reg", size=16, dest="Spare"),
1527              Operand(type="RM", size=16, relaxed=True, dest="EA")])
1528# Be careful with XCHG EAX, EAX in 64-bit mode.  This needs to use
1529# the long form rather than the NOP form, as the long form clears
1530# the high 32 bits of RAX.  This makes all 32-bit forms in 64-bit
1531# mode have consistent operation.
1532#
1533# FIXME: due to a hard-to-fix bug in how we handle generating gas suffix CPU
1534# rules, this causes xchgl to be CPU_Any instead of CPU_386.  A hacky patch
1535# could fix it, but it's doubtful anyone will ever notice, so leave it.
1536add_group("xchg",
1537    suffix="l",
1538    only64=True,
1539    opersize=32,
1540    opcode=[0x87],
1541    operands=[Operand(type="Areg", size=32, dest="EA"),
1542              Operand(type="Areg", size=32, dest="Spare")])
1543add_group("xchg",
1544    suffix="l",
1545    opersize=32,
1546    opcode=[0x90],
1547    operands=[Operand(type="Areg", size=32, dest=None),
1548              Operand(type="Reg", size=32, dest="Op0Add")])
1549add_group("xchg",
1550    suffix="l",
1551    opersize=32,
1552    opcode=[0x90],
1553    operands=[Operand(type="Reg", size=32, dest="Op0Add"),
1554              Operand(type="Areg", size=32, dest=None)])
1555add_group("xchg",
1556    suffix="l",
1557    opersize=32,
1558    opcode=[0x87],
1559    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
1560              Operand(type="Reg", size=32, dest="Spare")])
1561add_group("xchg",
1562    suffix="l",
1563    opersize=32,
1564    opcode=[0x87],
1565    operands=[Operand(type="Reg", size=32, dest="Spare"),
1566              Operand(type="RM", size=32, relaxed=True, dest="EA")])
1567# Be efficient with XCHG RAX, RAX.
1568# This is a NOP and thus doesn't need the REX prefix.
1569add_group("xchg",
1570    suffix="q",
1571    only64=True,
1572    opcode=[0x90],
1573    operands=[Operand(type="Areg", size=64, dest=None),
1574              Operand(type="Areg", size=64, dest="Op0Add")])
1575add_group("xchg",
1576    suffix="q",
1577    opersize=64,
1578    opcode=[0x90],
1579    operands=[Operand(type="Areg", size=64, dest=None),
1580              Operand(type="Reg", size=64, dest="Op0Add")])
1581add_group("xchg",
1582    suffix="q",
1583    opersize=64,
1584    opcode=[0x90],
1585    operands=[Operand(type="Reg", size=64, dest="Op0Add"),
1586              Operand(type="Areg", size=64, dest=None)])
1587add_group("xchg",
1588    suffix="q",
1589    opersize=64,
1590    opcode=[0x87],
1591    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
1592              Operand(type="Reg", size=64, dest="Spare")])
1593add_group("xchg",
1594    suffix="q",
1595    opersize=64,
1596    opcode=[0x87],
1597    operands=[Operand(type="Reg", size=64, dest="Spare"),
1598              Operand(type="RM", size=64, relaxed=True, dest="EA")])
1599
1600add_insn("xchg", "xchg")
1601
1602#####################################################################
1603# In/out from ports
1604#####################################################################
1605add_group("in",
1606    suffix="b",
1607    opcode=[0xE4],
1608    operands=[Operand(type="Areg", size=8, dest=None),
1609              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1610for sfx, sz in zip("wl", [16, 32]):
1611    add_group("in",
1612        suffix=sfx,
1613        opersize=sz,
1614        opcode=[0xE5],
1615        operands=[Operand(type="Areg", size=sz, dest=None),
1616                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1617add_group("in",
1618    suffix="b",
1619    opcode=[0xEC],
1620    operands=[Operand(type="Areg", size=8, dest=None),
1621              Operand(type="Dreg", size=16, dest=None)])
1622for sfx, sz in zip("wl", [16, 32]):
1623    add_group("in",
1624        suffix=sfx,
1625        opersize=sz,
1626        opcode=[0xED],
1627        operands=[Operand(type="Areg", size=sz, dest=None),
1628                  Operand(type="Dreg", size=16, dest=None)])
1629# GAS-only variants (implicit accumulator register)
1630add_group("in",
1631    suffix="b",
1632    parsers=["gas"],
1633    opcode=[0xE4],
1634    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1635for sfx, sz in zip("wl", [16, 32]):
1636    add_group("in",
1637        suffix=sfx,
1638        parsers=["gas"],
1639        opersize=sz,
1640        opcode=[0xE5],
1641        operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1642add_group("in",
1643    suffix="b",
1644    parsers=["gas"],
1645    opcode=[0xEC],
1646    operands=[Operand(type="Dreg", size=16, dest=None)])
1647add_group("in",
1648    suffix="w",
1649    parsers=["gas"],
1650    opersize=16,
1651    opcode=[0xED],
1652    operands=[Operand(type="Dreg", size=16, dest=None)])
1653add_group("in",
1654    suffix="l",
1655    cpu=["386"],
1656    parsers=["gas"],
1657    opersize=32,
1658    opcode=[0xED],
1659    operands=[Operand(type="Dreg", size=16, dest=None)])
1660
1661add_insn("in", "in")
1662
1663add_group("out",
1664    suffix="b",
1665    opcode=[0xE6],
1666    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm"),
1667              Operand(type="Areg", size=8, dest=None)])
1668for sfx, sz in zip("wl", [16, 32]):
1669    add_group("out",
1670        suffix=sfx,
1671        opersize=sz,
1672        opcode=[0xE7],
1673        operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm"),
1674                  Operand(type="Areg", size=sz, dest=None)])
1675add_group("out",
1676    suffix="b",
1677    opcode=[0xEE],
1678    operands=[Operand(type="Dreg", size=16, dest=None),
1679              Operand(type="Areg", size=8, dest=None)])
1680for sfx, sz in zip("wl", [16, 32]):
1681    add_group("out",
1682        suffix=sfx,
1683        opersize=sz,
1684        opcode=[0xEF],
1685        operands=[Operand(type="Dreg", size=16, dest=None),
1686                  Operand(type="Areg", size=sz, dest=None)])
1687# GAS-only variants (implicit accumulator register)
1688add_group("out",
1689    suffix="b",
1690    parsers=["gas"],
1691    opcode=[0xE6],
1692    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1693add_group("out",
1694    suffix="w",
1695    parsers=["gas"],
1696    opersize=16,
1697    opcode=[0xE7],
1698    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1699add_group("out",
1700    suffix="l",
1701    cpu=["386"],
1702    parsers=["gas"],
1703    opersize=32,
1704    opcode=[0xE7],
1705    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1706add_group("out",
1707    suffix="b",
1708    parsers=["gas"],
1709    opcode=[0xEE],
1710    operands=[Operand(type="Dreg", size=16, dest=None)])
1711add_group("out",
1712    suffix="w",
1713    parsers=["gas"],
1714    opersize=16,
1715    opcode=[0xEF],
1716    operands=[Operand(type="Dreg", size=16, dest=None)])
1717add_group("out",
1718    suffix="l",
1719    cpu=["386"],
1720    parsers=["gas"],
1721    opersize=32,
1722    opcode=[0xEF],
1723    operands=[Operand(type="Dreg", size=16, dest=None)])
1724
1725add_insn("out", "out")
1726
1727#
1728# Load effective address
1729#
1730for sfx, sz in zip("wlq", [16, 32, 64]):
1731    add_group("lea",
1732        suffix=sfx,
1733        opersize=sz,
1734        opcode=[0x8D],
1735        operands=[Operand(type="Reg", size=sz, dest="Spare"),
1736                  Operand(type="Mem", relaxed=True, dest="EA")])
1737
1738add_insn("lea", "lea")
1739
1740#
1741# Load segment registers from memory
1742#
1743for sfx, sz in zip("wl", [16, 32]):
1744    add_group("ldes",
1745        suffix=sfx,
1746        not64=True,
1747        modifiers=["Op0Add"],
1748        opersize=sz,
1749        opcode=[0x00],
1750        operands=[Operand(type="Reg", size=sz, dest="Spare"),
1751                  Operand(type="Mem", relaxed=True, dest="EA")])
1752
1753add_insn("lds", "ldes", modifiers=[0xC5])
1754add_insn("les", "ldes", modifiers=[0xC4])
1755
1756for sfx, sz in zip("wlq", [16, 32, 64]):
1757    add_group("lfgss",
1758        suffix=sfx,
1759        cpu=["386"],
1760        modifiers=["Op1Add"],
1761        opersize=sz,
1762        opcode=[0x0F, 0x00],
1763        operands=[Operand(type="Reg", size=sz, dest="Spare"),
1764                  Operand(type="Mem", relaxed=True, dest="EA")])
1765
1766add_insn("lfs", "lfgss", modifiers=[0xB4])
1767add_insn("lgs", "lfgss", modifiers=[0xB5])
1768add_insn("lss", "lfgss", modifiers=[0xB2])
1769
1770#
1771# Flags registers instructions
1772#
1773add_insn("clc", "onebyte", modifiers=[0xF8])
1774add_insn("cld", "onebyte", modifiers=[0xFC])
1775add_insn("cli", "onebyte", modifiers=[0xFA])
1776add_insn("clts", "twobyte", modifiers=[0x0F, 0x06], cpu=["286", "Priv"])
1777add_insn("cmc", "onebyte", modifiers=[0xF5])
1778add_insn("lahf", "onebyte", modifiers=[0x9F])
1779add_insn("sahf", "onebyte", modifiers=[0x9E])
1780add_insn("pushf", "onebyte", modifiers=[0x9C, 0, 64])
1781add_insn("pushfd", "onebyte", parser="nasm", modifiers=[0x9C, 32],
1782         cpu=["386"], not64=True)
1783add_insn("pushfl", "onebyte", parser="gas", modifiers=[0x9C, 32],
1784         cpu=["386"], not64=True)
1785add_insn("pushfw", "onebyte", modifiers=[0x9C, 16, 64])
1786add_insn("pushfq", "onebyte", modifiers=[0x9C, 64, 64], only64=True)
1787add_insn("popf", "onebyte", modifiers=[0x9D, 0, 64])
1788add_insn("popfd", "onebyte", parser="nasm", modifiers=[0x9D, 32],
1789         cpu=["386"], not64=True)
1790add_insn("popfl", "onebyte", parser="gas", modifiers=[0x9D, 32],
1791         cpu=["386"], not64=True)
1792add_insn("popfw", "onebyte", modifiers=[0x9D, 16, 64])
1793add_insn("popfq", "onebyte", modifiers=[0x9D, 64, 64], only64=True)
1794add_insn("stc", "onebyte", modifiers=[0xF9])
1795add_insn("std", "onebyte", modifiers=[0xFD])
1796add_insn("sti", "onebyte", modifiers=[0xFB])
1797
1798#
1799# Arithmetic - general
1800#
1801add_group("arith",
1802    suffix="b",
1803    modifiers=["Op0Add"],
1804    opcode=[0x04],
1805    operands=[Operand(type="Areg", size=8, dest=None),
1806              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1807for sfx, sz, immsz in zip("wlq", [16, 32, 64], [16, 32, 32]):
1808    add_group("arith",
1809        suffix=sfx,
1810        modifiers=["Op2Add", "Op1AddSp"],
1811        opersize=sz,
1812        opcode1=[0x83, 0xC0],
1813        opcode2=[0x05],
1814        operands=[Operand(type="Areg", size=sz, dest=None),
1815                  Operand(type="Imm", size=immsz, relaxed=True, dest="Imm",
1816                          opt="SImm8")])
1817
1818add_group("arith",
1819    suffix="b",
1820    modifiers=["Gap", "SpAdd"],
1821    opcode=[0x80],
1822    spare=0,
1823    operands=[Operand(type="RM", size=8, dest="EA"),
1824              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
1825add_group("arith",
1826    suffix="b",
1827    modifiers=["Gap", "SpAdd"],
1828    opcode=[0x80],
1829    spare=0,
1830    operands=[Operand(type="RM", size=8, relaxed=True, dest="EA"),
1831              Operand(type="Imm", size=8, dest="Imm")])
1832
1833add_group("arith",
1834    suffix="w",
1835    modifiers=["Gap", "SpAdd"],
1836    opersize=16,
1837    opcode=[0x83],
1838    spare=0,
1839    operands=[Operand(type="RM", size=16, dest="EA"),
1840              Operand(type="Imm", size=8, dest="SImm")])
1841add_group("arith",
1842    parsers=["nasm"],
1843    modifiers=["Gap", "SpAdd"],
1844    opersize=16,
1845    opcode1=[0x83],
1846    opcode2=[0x81],
1847    spare=0,
1848    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA"),
1849              Operand(type="Imm", size=16, dest="Imm", opt="SImm8")])
1850add_group("arith",
1851    suffix="w",
1852    modifiers=["Gap", "SpAdd"],
1853    opersize=16,
1854    opcode1=[0x83],
1855    opcode2=[0x81],
1856    spare=0,
1857    operands=[
1858        Operand(type="RM", size=16, dest="EA"),
1859        Operand(type="Imm", size=16, relaxed=True, dest="Imm", opt="SImm8")])
1860
1861add_group("arith",
1862    suffix="l",
1863    modifiers=["Gap", "SpAdd"],
1864    opersize=32,
1865    opcode=[0x83],
1866    spare=0,
1867    operands=[Operand(type="RM", size=32, dest="EA"),
1868              Operand(type="Imm", size=8, dest="SImm")])
1869# Not64 because we can't tell if add [], dword in 64-bit mode is supposed
1870# to be a qword destination or a dword destination.
1871add_group("arith",
1872    not64=True,
1873    parsers=["nasm"],
1874    modifiers=["Gap", "SpAdd"],
1875    opersize=32,
1876    opcode1=[0x83],
1877    opcode2=[0x81],
1878    spare=0,
1879    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
1880              Operand(type="Imm", size=32, dest="Imm", opt="SImm8")])
1881add_group("arith",
1882    suffix="l",
1883    modifiers=["Gap", "SpAdd"],
1884    opersize=32,
1885    opcode1=[0x83],
1886    opcode2=[0x81],
1887    spare=0,
1888    operands=[
1889        Operand(type="RM", size=32, dest="EA"),
1890        Operand(type="Imm", size=32, relaxed=True, dest="Imm", opt="SImm8")])
1891
1892# No relaxed-RM mode for 64-bit destinations; see above Not64 comment.
1893add_group("arith",
1894    suffix="q",
1895    modifiers=["Gap", "SpAdd"],
1896    opersize=64,
1897    opcode=[0x83],
1898    spare=0,
1899    operands=[Operand(type="RM", size=64, dest="EA"),
1900              Operand(type="Imm", size=8, dest="SImm")])
1901add_group("arith",
1902    suffix="q",
1903    modifiers=["Gap", "SpAdd"],
1904    opersize=64,
1905    opcode1=[0x83],
1906    opcode2=[0x81],
1907    spare=0,
1908    operands=[
1909        Operand(type="RM", size=64, dest="EA"),
1910        Operand(type="Imm", size=32, relaxed=True, dest="Imm", opt="SImm8")])
1911
1912for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
1913    add_group("arith",
1914        suffix=sfx,
1915        modifiers=["Op0Add"],
1916        opersize=sz,
1917        opcode=[0x00+(sz!=8)],
1918        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
1919                  Operand(type="Reg", size=sz, dest="Spare")])
1920for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
1921    add_group("arith",
1922        suffix=sfx,
1923        modifiers=["Op0Add"],
1924        opersize=sz,
1925        opcode=[0x02+(sz!=8)],
1926        operands=[Operand(type="Reg", size=sz, dest="Spare"),
1927                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
1928
1929add_insn("add", "arith", modifiers=[0x00, 0])
1930add_insn("or",  "arith", modifiers=[0x08, 1])
1931add_insn("adc", "arith", modifiers=[0x10, 2])
1932add_insn("sbb", "arith", modifiers=[0x18, 3])
1933add_insn("and", "arith", modifiers=[0x20, 4])
1934add_insn("sub", "arith", modifiers=[0x28, 5])
1935add_insn("xor", "arith", modifiers=[0x30, 6])
1936add_insn("cmp", "arith", modifiers=[0x38, 7])
1937
1938#
1939# Arithmetic - inc/dec
1940#
1941add_group("incdec",
1942    suffix="b",
1943    modifiers=["Gap", "SpAdd"],
1944    opcode=[0xFE],
1945    spare=0,
1946    operands=[Operand(type="RM", size=8, dest="EA")])
1947for sfx, sz in zip("wl", [16, 32]):
1948    add_group("incdec",
1949        suffix=sfx,
1950        not64=True,
1951        modifiers=["Op0Add"],
1952        opersize=sz,
1953        opcode=[0x00],
1954        operands=[Operand(type="Reg", size=sz, dest="Op0Add")])
1955    add_group("incdec",
1956        suffix=sfx,
1957        modifiers=["Gap", "SpAdd"],
1958        opersize=sz,
1959        opcode=[0xFF],
1960        spare=0,
1961        operands=[Operand(type="RM", size=sz, dest="EA")])
1962add_group("incdec",
1963    suffix="q",
1964    modifiers=["Gap", "SpAdd"],
1965    opersize=64,
1966    opcode=[0xFF],
1967    spare=0,
1968    operands=[Operand(type="RM", size=64, dest="EA")])
1969
1970add_insn("inc", "incdec", modifiers=[0x40, 0])
1971add_insn("dec", "incdec", modifiers=[0x48, 1])
1972
1973#
1974# Arithmetic - mul/neg/not F6 opcodes
1975#
1976for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
1977    add_group("f6",
1978        suffix=sfx,
1979        modifiers=["SpAdd"],
1980        opersize=sz,
1981        opcode=[0xF6+(sz!=8)],
1982        spare=0,
1983        operands=[Operand(type="RM", size=sz, dest="EA")])
1984
1985add_insn("not", "f6", modifiers=[2])
1986add_insn("neg", "f6", modifiers=[3])
1987add_insn("mul", "f6", modifiers=[4])
1988
1989#
1990# Arithmetic - div/idiv F6 opcodes
1991# These allow explicit accumulator in GAS mode.
1992#
1993for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
1994    add_group("div",
1995        suffix=sfx,
1996        modifiers=["SpAdd"],
1997        opersize=sz,
1998        opcode=[0xF6+(sz!=8)],
1999        spare=0,
2000        operands=[Operand(type="RM", size=sz, dest="EA")])
2001# Versions with explicit accumulator
2002for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2003    add_group("div",
2004        suffix=sfx,
2005        modifiers=["SpAdd"],
2006        opersize=sz,
2007        opcode=[0xF6+(sz!=8)],
2008        spare=0,
2009        operands=[Operand(type="Areg", size=sz, dest=None),
2010                  Operand(type="RM", size=sz, dest="EA")])
2011
2012add_insn("div", "div", modifiers=[6])
2013add_insn("idiv", "div", modifiers=[7])
2014
2015#
2016# Arithmetic - test instruction
2017#
2018for sfx, sz, immsz in zip("bwlq", [8, 16, 32, 64], [8, 16, 32, 32]):
2019    add_group("test",
2020        suffix=sfx,
2021        opersize=sz,
2022        opcode=[0xA8+(sz!=8)],
2023        operands=[Operand(type="Areg", size=sz, dest=None),
2024                  Operand(type="Imm", size=immsz, relaxed=True, dest="Imm")])
2025
2026for sfx, sz, immsz in zip("bwlq", [8, 16, 32, 64], [8, 16, 32, 32]):
2027    add_group("test",
2028        suffix=sfx,
2029        opersize=sz,
2030        opcode=[0xF6+(sz!=8)],
2031        operands=[Operand(type="RM", size=sz, dest="EA"),
2032                  Operand(type="Imm", size=immsz, relaxed=True, dest="Imm")])
2033    add_group("test",
2034        suffix=sfx,
2035        opersize=sz,
2036        opcode=[0xF6+(sz!=8)],
2037        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2038                  Operand(type="Imm", size=immsz, dest="Imm")])
2039
2040for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2041    add_group("test",
2042        suffix=sfx,
2043        opersize=sz,
2044        opcode=[0x84+(sz!=8)],
2045        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2046                  Operand(type="Reg", size=sz, dest="Spare")])
2047for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2048    add_group("test",
2049        suffix=sfx,
2050        opersize=sz,
2051        opcode=[0x84+(sz!=8)],
2052        operands=[Operand(type="Reg", size=sz, dest="Spare"),
2053                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
2054
2055add_insn("test", "test")
2056
2057#
2058# Arithmetic - aad/aam
2059#
2060add_group("aadm",
2061    modifiers=["Op0Add"],
2062    opcode=[0xD4, 0x0A],
2063    operands=[])
2064add_group("aadm",
2065    modifiers=["Op0Add"],
2066    opcode=[0xD4],
2067    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2068
2069add_insn("aaa", "onebyte", modifiers=[0x37], not64=True)
2070add_insn("aas", "onebyte", modifiers=[0x3F], not64=True)
2071add_insn("daa", "onebyte", modifiers=[0x27], not64=True)
2072add_insn("das", "onebyte", modifiers=[0x2F], not64=True)
2073add_insn("aad", "aadm", modifiers=[0x01], not64=True)
2074add_insn("aam", "aadm", modifiers=[0x00], not64=True)
2075
2076#
2077# Conversion instructions
2078#
2079add_insn("cbw", "onebyte", modifiers=[0x98, 16])
2080add_insn("cwde", "onebyte", modifiers=[0x98, 32], cpu=["386"])
2081add_insn("cdqe", "onebyte", modifiers=[0x98, 64], only64=True)
2082add_insn("cwd", "onebyte", modifiers=[0x99, 16])
2083add_insn("cdq", "onebyte", modifiers=[0x99, 32], cpu=["386"])
2084add_insn("cqo", "onebyte", modifiers=[0x99, 64], only64=True)
2085
2086#
2087# Conversion instructions - GAS / AT&T naming
2088#
2089add_insn("cbtw", "onebyte", parser="gas", modifiers=[0x98, 16])
2090add_insn("cwtl", "onebyte", parser="gas", modifiers=[0x98, 32], cpu=["386"])
2091add_insn("cltq", "onebyte", parser="gas", modifiers=[0x98, 64], only64=True)
2092add_insn("cwtd", "onebyte", parser="gas", modifiers=[0x99, 16])
2093add_insn("cltd", "onebyte", parser="gas", modifiers=[0x99, 32], cpu=["386"])
2094add_insn("cqto", "onebyte", parser="gas", modifiers=[0x99, 64], only64=True)
2095
2096#
2097# Arithmetic - imul
2098#
2099for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2100    add_group("imul",
2101        suffix=sfx,
2102        opersize=sz,
2103        opcode=[0xF6+(sz!=8)],
2104        spare=5,
2105        operands=[Operand(type="RM", size=sz, dest="EA")])
2106for sfx, sz in zip("wlq", [16, 32, 64]):
2107    add_group("imul",
2108        suffix=sfx,
2109        cpu=["386"],
2110        opersize=sz,
2111        opcode=[0x0F, 0xAF],
2112        operands=[Operand(type="Reg", size=sz, dest="Spare"),
2113                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
2114for sfx, sz in zip("wlq", [16, 32, 64]):
2115    add_group("imul",
2116        suffix=sfx,
2117        cpu=["186"],
2118        opersize=sz,
2119        opcode=[0x6B],
2120        operands=[Operand(type="Reg", size=sz, dest="Spare"),
2121                  Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2122                  Operand(type="Imm", size=8, dest="SImm")])
2123for sfx, sz in zip("wlq", [16, 32, 64]):
2124    add_group("imul",
2125        suffix=sfx,
2126        cpu=["186"],
2127        opersize=sz,
2128        opcode=[0x6B],
2129        operands=[Operand(type="Reg", size=sz, dest="SpareEA"),
2130                  Operand(type="Imm", size=8, dest="SImm")])
2131for sfx, sz, immsz in zip("wlq", [16, 32, 64], [16, 32, 32]):
2132    add_group("imul",
2133        suffix=sfx,
2134        cpu=["186"],
2135        opersize=sz,
2136        opcode1=[0x6B],
2137        opcode2=[0x69],
2138        operands=[Operand(type="Reg", size=sz, dest="Spare"),
2139                  Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2140                  Operand(type="Imm", size=immsz, relaxed=True, dest="SImm",
2141                          opt="SImm8")])
2142for sfx, sz, immsz in zip("wlq", [16, 32, 64], [16, 32, 32]):
2143    add_group("imul",
2144        suffix=sfx,
2145        cpu=["186"],
2146        opersize=sz,
2147        opcode1=[0x6B],
2148        opcode2=[0x69],
2149        operands=[Operand(type="Reg", size=sz, dest="SpareEA"),
2150                  Operand(type="Imm", size=immsz, relaxed=True, dest="SImm",
2151                          opt="SImm8")])
2152
2153add_insn("imul", "imul")
2154
2155#
2156# Shifts - standard
2157#
2158for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2159    add_group("shift",
2160        suffix=sfx,
2161        modifiers=["SpAdd"],
2162        opersize=sz,
2163        opcode=[0xD2+(sz!=8)],
2164        spare=0,
2165        operands=[Operand(type="RM", size=sz, dest="EA"),
2166                  Operand(type="Creg", size=8, dest=None)])
2167    add_group("shift",
2168        suffix=sfx,
2169        modifiers=["SpAdd"],
2170        opersize=sz,
2171        opcode=[0xD0+(sz!=8)],
2172        spare=0,
2173        operands=[Operand(type="RM", size=sz, dest="EA"),
2174                  Operand(type="Imm1", size=8, relaxed=True, dest=None)])
2175    add_group("shift",
2176        suffix=sfx,
2177        cpu=["186"],
2178        modifiers=["SpAdd"],
2179        opersize=sz,
2180        opcode=[0xC0+(sz!=8)],
2181        spare=0,
2182        operands=[Operand(type="RM", size=sz, dest="EA"),
2183                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2184# In GAS mode, single operands are equivalent to shifting by 1 forms
2185for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
2186    add_group("shift",
2187        suffix=sfx,
2188        parsers=["gas"],
2189        modifiers=["SpAdd"],
2190        opersize=sz,
2191        opcode=[0xD0+(sz!=8)],
2192        spare=0,
2193        operands=[Operand(type="RM", size=sz, dest="EA")])
2194
2195add_insn("rol", "shift", modifiers=[0])
2196add_insn("ror", "shift", modifiers=[1])
2197add_insn("rcl", "shift", modifiers=[2])
2198add_insn("rcr", "shift", modifiers=[3])
2199add_insn("sal", "shift", modifiers=[4])
2200add_insn("shl", "shift", modifiers=[4])
2201add_insn("shr", "shift", modifiers=[5])
2202add_insn("sar", "shift", modifiers=[7])
2203
2204#
2205# Shifts - doubleword
2206#
2207for sfx, sz in zip("wlq", [16, 32, 64]):
2208    add_group("shlrd",
2209        suffix=sfx,
2210        cpu=["386"],
2211        modifiers=["Op1Add"],
2212        opersize=sz,
2213        opcode=[0x0F, 0x00],
2214        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2215                  Operand(type="Reg", size=sz, dest="Spare"),
2216                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2217    add_group("shlrd",
2218        suffix=sfx,
2219        cpu=["386"],
2220        modifiers=["Op1Add"],
2221        opersize=sz,
2222        opcode=[0x0F, 0x01],
2223        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2224                  Operand(type="Reg", size=sz, dest="Spare"),
2225                  Operand(type="Creg", size=8, dest=None)])
2226# GAS parser supports two-operand form for shift with CL count
2227for sfx, sz in zip("wlq", [16, 32, 64]):
2228    add_group("shlrd",
2229        suffix=sfx,
2230        cpu=["386"],
2231        parsers=["gas"],
2232        modifiers=["Op1Add"],
2233        opersize=sz,
2234        opcode=[0x0F, 0x01],
2235        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
2236                  Operand(type="Reg", size=sz, dest="Spare")])
2237
2238add_insn("shld", "shlrd", modifiers=[0xA4])
2239add_insn("shrd", "shlrd", modifiers=[0xAC])
2240
2241#####################################################################
2242# Control transfer instructions (unconditional)
2243#####################################################################
2244#
2245# call
2246#
2247add_group("call",
2248    opcode=[],
2249    operands=[Operand(type="ImmNotSegOff", dest="JmpRel")])
2250add_group("call",
2251    suffix="w",
2252    opersize=16,
2253    opcode=[],
2254    operands=[Operand(type="ImmNotSegOff", size=16, dest="JmpRel")])
2255add_group("call",
2256    suffix="l",
2257    not64=True,
2258    opersize=32,
2259    opcode=[],
2260    operands=[Operand(type="ImmNotSegOff", size=32, dest="JmpRel")])
2261add_group("call",
2262    suffixes=["l", "q"],
2263    only64=True,
2264    opersize=64,
2265    opcode=[],
2266    operands=[Operand(type="ImmNotSegOff", size=32, dest="JmpRel")])
2267
2268add_group("call",
2269    opersize=16,
2270    def_opersize_64=64,
2271    opcode=[0xE8],
2272    operands=[Operand(type="Imm", size=16, tmod="Near", dest="JmpRel")])
2273add_group("call",
2274    not64=True,
2275    opersize=32,
2276    opcode=[0xE8],
2277    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2278add_group("call",
2279    only64=True,
2280    opersize=64,
2281    def_opersize_64=64,
2282    opcode=[0xE8],
2283    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2284add_group("call",
2285    def_opersize_64=64,
2286    opcode=[0xE8],
2287    operands=[Operand(type="Imm", tmod="Near", dest="JmpRel")])
2288
2289add_group("call",
2290    suffix="w",
2291    req_suffix=True,
2292    opersize=16,
2293    opcode=[0xFF],
2294    spare=2,
2295    operands=[Operand(type="RM", size=16, dest="EA")])
2296add_group("call",
2297    suffix="l",
2298    req_suffix=True,
2299    not64=True,
2300    opersize=32,
2301    opcode=[0xFF],
2302    spare=2,
2303    operands=[Operand(type="RM", size=32, dest="EA")])
2304add_group("call",
2305    suffix="q",
2306    req_suffix=True,
2307    opersize=64,
2308    def_opersize_64=64,
2309    opcode=[0xFF],
2310    spare=2,
2311    operands=[Operand(type="RM", size=64, dest="EA")])
2312add_group("call",
2313    parsers=["gas"],
2314    def_opersize_64=64,
2315    opcode=[0xFF],
2316    spare=2,
2317    operands=[Operand(type="Reg", size="BITS", dest="EA")])
2318add_group("call",
2319    def_opersize_64=64,
2320    opcode=[0xFF],
2321    spare=2,
2322    operands=[Operand(type="Mem", dest="EA")])
2323add_group("call",
2324    parsers=["nasm"],
2325    opersize=16,
2326    def_opersize_64=64,
2327    opcode=[0xFF],
2328    spare=2,
2329    operands=[Operand(type="RM", size=16, tmod="Near", dest="EA")])
2330add_group("call",
2331    parsers=["nasm"],
2332    not64=True,
2333    opersize=32,
2334    opcode=[0xFF],
2335    spare=2,
2336    operands=[Operand(type="RM", size=32, tmod="Near", dest="EA")])
2337add_group("call",
2338    parsers=["nasm"],
2339    opersize=64,
2340    def_opersize_64=64,
2341    opcode=[0xFF],
2342    spare=2,
2343    operands=[Operand(type="RM", size=64, tmod="Near", dest="EA")])
2344add_group("call",
2345    parsers=["nasm"],
2346    def_opersize_64=64,
2347    opcode=[0xFF],
2348    spare=2,
2349    operands=[Operand(type="Mem", tmod="Near", dest="EA")])
2350
2351# Far indirect (through memory).  Needs explicit FAR override (NASM only)
2352for sz in [16, 32, 64]:
2353    add_group("call",
2354        parsers=["nasm"],
2355        opersize=sz,
2356        opcode=[0xFF],
2357        spare=3,
2358        operands=[Operand(type="Mem", size=sz, tmod="Far", dest="EA")])
2359add_group("call",
2360    parsers=["nasm"],
2361    opcode=[0xFF],
2362    spare=3,
2363    operands=[Operand(type="Mem", tmod="Far", dest="EA")])
2364
2365# With explicit FAR override
2366for sz in [16, 32]:
2367    add_group("call",
2368        parsers=["nasm"],
2369        not64=True,
2370        opersize=sz,
2371        opcode=[0x9A],
2372        operands=[Operand(type="Imm", size=sz, tmod="Far", dest="JmpFar")])
2373add_group("call",
2374    parsers=["nasm"],
2375    not64=True,
2376    opcode=[0x9A],
2377    operands=[Operand(type="Imm", tmod="Far", dest="JmpFar")])
2378
2379# Since not caught by first ImmNotSegOff group, implicitly FAR (in NASM).
2380for sz in [16, 32]:
2381    add_group("call",
2382        parsers=["nasm"],
2383        not64=True,
2384        opersize=sz,
2385        opcode=[0x9A],
2386        operands=[Operand(type="Imm", size=sz, dest="JmpFar")])
2387add_group("call",
2388    parsers=["nasm"],
2389    not64=True,
2390    opcode=[0x9A],
2391    operands=[Operand(type="Imm", dest="JmpFar")])
2392
2393# Two-operand FAR (GAS only)
2394for sfx, sz in zip("wl", [16, 32]):
2395    add_group("call",
2396        suffix=sfx,
2397        req_suffix=True,
2398        parsers=["gas"],
2399        not64=True,
2400        gas_no_reverse=True,
2401        opersize=sz,
2402        opcode=[0x9A],
2403        operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2404                  Operand(type="Imm", size=sz, relaxed=True, dest="JmpFar")])
2405add_group("call",
2406    parsers=["gas"],
2407    not64=True,
2408    gas_no_reverse=True,
2409    opcode=[0x9A],
2410    operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2411              Operand(type="Imm", size="BITS", relaxed=True, dest="JmpFar")])
2412
2413add_insn("call", "call")
2414
2415#
2416# jmp
2417#
2418add_group("jmp",
2419    opcode=[],
2420    operands=[Operand(type="ImmNotSegOff", dest="JmpRel")])
2421add_group("jmp",
2422    suffix="w",
2423    opersize=16,
2424    opcode=[],
2425    operands=[Operand(type="ImmNotSegOff", size=16, dest="JmpRel")])
2426add_group("jmp",
2427    suffix="l",
2428    not64=True,
2429    opersize=32,
2430    opcode=[0x00],
2431    operands=[Operand(type="ImmNotSegOff", size=32, dest="JmpRel")])
2432add_group("jmp",
2433    suffixes=["l", "q"],
2434    only64=True,
2435    opersize=64,
2436    opcode=[0x00],
2437    operands=[Operand(type="ImmNotSegOff", size=32, dest="JmpRel")])
2438
2439add_group("jmp",
2440    def_opersize_64=64,
2441    opcode=[0xEB],
2442    operands=[Operand(type="Imm", tmod="Short", dest="JmpRel")])
2443add_group("jmp",
2444    opersize=16,
2445    def_opersize_64=64,
2446    opcode=[0xE9],
2447    operands=[Operand(type="Imm", size=16, tmod="Near", dest="JmpRel")])
2448add_group("jmp",
2449    not64=True,
2450    cpu=["386"],
2451    opersize=32,
2452    opcode=[0xE9],
2453    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2454add_group("jmp",
2455    only64=True,
2456    opersize=64,
2457    def_opersize_64=64,
2458    opcode=[0xE9],
2459    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2460add_group("jmp",
2461    def_opersize_64=64,
2462    opcode=[0xE9],
2463    operands=[Operand(type="Imm", tmod="Near", dest="JmpRel")])
2464
2465add_group("jmp",
2466    suffix="w",
2467    req_suffix=True,
2468    opersize=16,
2469    def_opersize_64=64,
2470    opcode=[0xFF],
2471    spare=4,
2472    operands=[Operand(type="RM", size=16, dest="EA")])
2473add_group("jmp",
2474    suffix="l",
2475    req_suffix=True,
2476    not64=True,
2477    opersize=32,
2478    opcode=[0xFF],
2479    spare=4,
2480    operands=[Operand(type="RM", size=32, dest="EA")])
2481add_group("jmp",
2482    suffix="q",
2483    req_suffix=True,
2484    opersize=64,
2485    def_opersize_64=64,
2486    opcode=[0xFF],
2487    spare=4,
2488    operands=[Operand(type="RM", size=64, dest="EA")])
2489add_group("jmp",
2490    parsers=["gas"],
2491    def_opersize_64=64,
2492    opcode=[0xFF],
2493    spare=4,
2494    operands=[Operand(type="Reg", size="BITS", dest="EA")])
2495add_group("jmp",
2496    def_opersize_64=64,
2497    opcode=[0xFF],
2498    spare=4,
2499    operands=[Operand(type="Mem", dest="EA")])
2500add_group("jmp",
2501    parsers=["nasm"],
2502    opersize=16,
2503    def_opersize_64=64,
2504    opcode=[0xFF],
2505    spare=4,
2506    operands=[Operand(type="RM", size=16, tmod="Near", dest="EA")])
2507add_group("jmp",
2508    parsers=["nasm"],
2509    not64=True,
2510    cpu=["386"],
2511    opersize=32,
2512    opcode=[0xFF],
2513    spare=4,
2514    operands=[Operand(type="RM", size=32, tmod="Near", dest="EA")])
2515add_group("jmp",
2516    parsers=["nasm"],
2517    opersize=64,
2518    def_opersize_64=64,
2519    opcode=[0xFF],
2520    spare=4,
2521    operands=[Operand(type="RM", size=64, tmod="Near", dest="EA")])
2522add_group("jmp",
2523    parsers=["nasm"],
2524    def_opersize_64=64,
2525    opcode=[0xFF],
2526    spare=4,
2527    operands=[Operand(type="Mem", tmod="Near", dest="EA")])
2528
2529# Far indirect (through memory).  Needs explicit FAR override.
2530for sz in [16, 32, 64]:
2531    add_group("jmp",
2532        opersize=sz,
2533        opcode=[0xFF],
2534        spare=5,
2535        operands=[Operand(type="Mem", size=sz, tmod="Far", dest="EA")])
2536add_group("jmp",
2537    opcode=[0xFF],
2538    spare=5,
2539    operands=[Operand(type="Mem", tmod="Far", dest="EA")])
2540
2541# With explicit FAR override
2542for sz in [16, 32]:
2543    add_group("jmp",
2544        not64=True,
2545        opersize=sz,
2546        opcode=[0xEA],
2547        operands=[Operand(type="Imm", size=sz, tmod="Far", dest="JmpFar")])
2548add_group("jmp",
2549    not64=True,
2550    opcode=[0xEA],
2551    operands=[Operand(type="Imm", tmod="Far", dest="JmpFar")])
2552
2553# Since not caught by first ImmNotSegOff group, implicitly FAR (in NASM).
2554for sz in [16, 32]:
2555    add_group("jmp",
2556        parsers=["nasm"],
2557        not64=True,
2558        opersize=sz,
2559        opcode=[0xEA],
2560        operands=[Operand(type="Imm", size=sz, dest="JmpFar")])
2561add_group("jmp",
2562    parsers=["nasm"],
2563    not64=True,
2564    opcode=[0xEA],
2565    operands=[Operand(type="Imm", dest="JmpFar")])
2566
2567# Two-operand FAR (GAS only)
2568for sfx, sz in zip("wl", [16, 32]):
2569    add_group("jmp",
2570        parsers=["gas"],
2571        suffix=sfx,
2572        req_suffix=True,
2573        not64=True,
2574        gas_no_reverse=True,
2575        opersize=sz,
2576        opcode=[0xEA],
2577        operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2578                  Operand(type="Imm", size=sz, relaxed=True, dest="JmpFar")])
2579add_group("jmp",
2580    parsers=["gas"],
2581    not64=True,
2582    gas_no_reverse=True,
2583    opcode=[0xEA],
2584    operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2585              Operand(type="Imm", size="BITS", relaxed=True, dest="JmpFar")])
2586
2587add_insn("jmp", "jmp")
2588
2589#
2590# GAS far calls/jumps
2591#
2592
2593# Far indirect (through memory)
2594for sfx, sz in zip("wlq", [16, 32, 64]):
2595    add_group("ljmpcall",
2596        suffix=sfx,
2597        req_suffix=True,
2598        opersize=sz,
2599        modifiers=["SpAdd"],
2600        opcode=[0xFF],
2601        spare=0,
2602        operands=[Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
2603add_group("ljmpcall",
2604    modifiers=["SpAdd"],
2605    opcode=[0xFF],
2606    spare=0,
2607    operands=[Operand(type="Mem", size="BITS", relaxed=True, dest="EA")])
2608
2609# Two-operand far
2610for sfx, sz in zip("wl", [16, 32]):
2611    add_group("ljmpcall",
2612        not64=True,
2613        gas_no_reverse=True,
2614        suffix=sfx,
2615        req_suffix=True,
2616        opersize=sz,
2617        modifiers=["Gap", "Op0Add"],
2618        opcode=[0x00],
2619        operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2620                  Operand(type="Imm", size=sz, relaxed=True, dest="JmpFar")])
2621add_group("ljmpcall",
2622    not64=True,
2623    gas_no_reverse=True,
2624    modifiers=["Gap", "Op0Add"],
2625    opcode=[0x00],
2626    operands=[Operand(type="Imm", size=16, relaxed=True, dest="JmpFar"),
2627              Operand(type="Imm", size="BITS", relaxed=True, dest="JmpFar")])
2628
2629add_insn("ljmp", "ljmpcall", parser="gas", modifiers=[5, 0xEA])
2630add_insn("lcall", "ljmpcall", parser="gas", modifiers=[3, 0x9A])
2631
2632#
2633# ret
2634#
2635add_group("retnf",
2636    not64=True,
2637    modifiers=["Op0Add"],
2638    opcode=[0x01],
2639    operands=[])
2640add_group("retnf",
2641    not64=True,
2642    modifiers=["Op0Add"],
2643    opcode=[0x00],
2644    operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm")])
2645add_group("retnf",
2646    only64=True,
2647    modifiers=["Op0Add", "OpSizeR"],
2648    opcode=[0x01],
2649    operands=[])
2650add_group("retnf",
2651    only64=True,
2652    modifiers=["Op0Add", "OpSizeR"],
2653    opcode=[0x00],
2654    operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm")])
2655add_group("retnf",
2656    gen_suffix=False,
2657    suffixes=["w", "l", "q"],
2658    modifiers=["Op0Add", "OpSizeR"],
2659    opcode=[0x01],
2660    operands=[])
2661# GAS suffix versions
2662add_group("retnf",
2663    gen_suffix=False,
2664    suffixes=["w", "l", "q"],
2665    modifiers=["Op0Add", "OpSizeR"],
2666    opcode=[0x00],
2667    operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm")])
2668
2669add_insn("ret", "retnf", modifiers=[0xC2])
2670add_insn("retw", "retnf", parser="gas", modifiers=[0xC2, 16])
2671add_insn("retl", "retnf", parser="gas", modifiers=[0xC2], not64=True)
2672add_insn("retq", "retnf", parser="gas", modifiers=[0xC2], only64=True)
2673add_insn("retn", "retnf", parser="nasm", modifiers=[0xC2])
2674add_insn("retf", "retnf", parser="nasm", modifiers=[0xCA, 64])
2675add_insn("lret", "retnf", parser="gas", modifiers=[0xCA], suffix="z")
2676add_insn("lretw", "retnf", parser="gas", modifiers=[0xCA, 16], suffix="w")
2677add_insn("lretl", "retnf", parser="gas", modifiers=[0xCA], suffix="l")
2678add_insn("lretq", "retnf", parser="gas", modifiers=[0xCA, 64], only64=True,
2679         suffix="q")
2680
2681#
2682# enter
2683#
2684add_group("enter",
2685    suffix="l",
2686    not64=True,
2687    cpu=["186"],
2688    gas_no_reverse=True,
2689    opcode=[0xC8],
2690    operands=[
2691        Operand(type="Imm", size=16, relaxed=True, dest="EA", opt="A16"),
2692        Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2693add_group("enter",
2694    suffix="q",
2695    only64=True,
2696    cpu=["186"],
2697    gas_no_reverse=True,
2698    opersize=64,
2699    def_opersize_64=64,
2700    opcode=[0xC8],
2701    operands=[
2702        Operand(type="Imm", size=16, relaxed=True, dest="EA", opt="A16"),
2703        Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2704# GAS suffix version
2705add_group("enter",
2706    suffix="w",
2707    cpu=["186"],
2708    parsers=["gas"],
2709    gas_no_reverse=True,
2710    opersize=16,
2711    opcode=[0xC8],
2712    operands=[
2713        Operand(type="Imm", size=16, relaxed=True, dest="EA", opt="A16"),
2714        Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
2715
2716add_insn("enter", "enter")
2717
2718#
2719# leave
2720#
2721add_insn("leave", "onebyte", modifiers=[0xC9, 0, 64], cpu=["186"])
2722add_insn("leavew", "onebyte", parser="gas", modifiers=[0xC9, 16, 0],
2723         cpu=["186"])
2724add_insn("leavel", "onebyte", parser="gas", modifiers=[0xC9, 0, 64],
2725         cpu=["186"])
2726add_insn("leaveq", "onebyte", parser="gas", modifiers=[0xC9, 0, 64],
2727         only64=True)
2728
2729#####################################################################
2730# Conditional jumps
2731#####################################################################
2732add_group("jcc",
2733    opcode=[],
2734    operands=[Operand(type="Imm", dest="JmpRel")])
2735add_group("jcc",
2736    opersize=16,
2737    opcode=[],
2738    operands=[Operand(type="Imm", size=16, dest="JmpRel")])
2739add_group("jcc",
2740    not64=True,
2741    opersize=32,
2742    opcode=[],
2743    operands=[Operand(type="Imm", size=32, dest="JmpRel")])
2744add_group("jcc",
2745    only64=True,
2746    opersize=64,
2747    opcode=[],
2748    operands=[Operand(type="Imm", size=32, dest="JmpRel")])
2749
2750add_group("jcc",
2751    modifiers=["Op0Add"],
2752    def_opersize_64=64,
2753    opcode=[0x70],
2754    operands=[Operand(type="Imm", tmod="Short", dest="JmpRel")])
2755add_group("jcc",
2756    cpu=["186"],
2757    modifiers=["Op1Add"],
2758    opersize=16,
2759    def_opersize_64=64,
2760    opcode=[0x0F, 0x80],
2761    operands=[Operand(type="Imm", size=16, tmod="Near", dest="JmpRel")])
2762add_group("jcc",
2763    not64=True,
2764    cpu=["386"],
2765    modifiers=["Op1Add"],
2766    opersize=32,
2767    opcode=[0x0F, 0x80],
2768    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2769add_group("jcc",
2770    only64=True,
2771    modifiers=["Op1Add"],
2772    opersize=64,
2773    def_opersize_64=64,
2774    opcode=[0x0F, 0x80],
2775    operands=[Operand(type="Imm", size=32, tmod="Near", dest="JmpRel")])
2776add_group("jcc",
2777    cpu=["186"],
2778    modifiers=["Op1Add"],
2779    def_opersize_64=64,
2780    opcode=[0x0F, 0x80],
2781    operands=[Operand(type="Imm", tmod="Near", dest="JmpRel")])
2782
2783add_insn("jo", "jcc", modifiers=[0x00])
2784add_insn("jno", "jcc", modifiers=[0x01])
2785add_insn("jb", "jcc", modifiers=[0x02])
2786add_insn("jc", "jcc", modifiers=[0x02])
2787add_insn("jnae", "jcc", modifiers=[0x02])
2788add_insn("jnb", "jcc", modifiers=[0x03])
2789add_insn("jnc", "jcc", modifiers=[0x03])
2790add_insn("jae", "jcc", modifiers=[0x03])
2791add_insn("je", "jcc", modifiers=[0x04])
2792add_insn("jz", "jcc", modifiers=[0x04])
2793add_insn("jne", "jcc", modifiers=[0x05])
2794add_insn("jnz", "jcc", modifiers=[0x05])
2795add_insn("jbe", "jcc", modifiers=[0x06])
2796add_insn("jna", "jcc", modifiers=[0x06])
2797add_insn("jnbe", "jcc", modifiers=[0x07])
2798add_insn("ja", "jcc", modifiers=[0x07])
2799add_insn("js", "jcc", modifiers=[0x08])
2800add_insn("jns", "jcc", modifiers=[0x09])
2801add_insn("jp", "jcc", modifiers=[0x0A])
2802add_insn("jpe", "jcc", modifiers=[0x0A])
2803add_insn("jnp", "jcc", modifiers=[0x0B])
2804add_insn("jpo", "jcc", modifiers=[0x0B])
2805add_insn("jl", "jcc", modifiers=[0x0C])
2806add_insn("jnge", "jcc", modifiers=[0x0C])
2807add_insn("jnl", "jcc", modifiers=[0x0D])
2808add_insn("jge", "jcc", modifiers=[0x0D])
2809add_insn("jle", "jcc", modifiers=[0x0E])
2810add_insn("jng", "jcc", modifiers=[0x0E])
2811add_insn("jnle", "jcc", modifiers=[0x0F])
2812add_insn("jg", "jcc", modifiers=[0x0F])
2813
2814#
2815# jcxz
2816#
2817add_group("jcxz",
2818    modifiers=["AdSizeR"],
2819    opcode=[],
2820    operands=[Operand(type="Imm", dest="JmpRel")])
2821add_group("jcxz",
2822    modifiers=["AdSizeR"],
2823    def_opersize_64=64,
2824    opcode=[0xE3],
2825    operands=[Operand(type="Imm", tmod="Short", dest="JmpRel")])
2826
2827add_insn("jcxz", "jcxz", modifiers=[16])
2828add_insn("jecxz", "jcxz", modifiers=[32], cpu=["386"])
2829add_insn("jrcxz", "jcxz", modifiers=[64], only64=True)
2830
2831#####################################################################
2832# Loop instructions
2833#####################################################################
2834add_group("loop",
2835    opcode=[],
2836    operands=[Operand(type="Imm", dest="JmpRel")])
2837add_group("loop",
2838    not64=True,
2839    opcode=[],
2840    operands=[Operand(type="Imm", dest="JmpRel"),
2841              Operand(type="Creg", size=16, dest="AdSizeR")])
2842add_group("loop",
2843    def_opersize_64=64,
2844    opcode=[],
2845    operands=[Operand(type="Imm", dest="JmpRel"),
2846              Operand(type="Creg", size=32, dest="AdSizeR")])
2847add_group("loop",
2848    def_opersize_64=64,
2849    opcode=[],
2850    operands=[Operand(type="Imm", dest="JmpRel"),
2851              Operand(type="Creg", size=64, dest="AdSizeR")])
2852
2853add_group("loop",
2854    not64=True,
2855    modifiers=["Op0Add"],
2856    opcode=[0xE0],
2857    operands=[Operand(type="Imm", tmod="Short", dest="JmpRel")])
2858for sz in [16, 32, 64]:
2859    add_group("loop",
2860        modifiers=["Op0Add"],
2861        def_opersize_64=64,
2862        opcode=[0xE0],
2863        operands=[Operand(type="Imm", tmod="Short", dest="JmpRel"),
2864                  Operand(type="Creg", size=sz, dest="AdSizeR")])
2865
2866add_insn("loop", "loop", modifiers=[2])
2867add_insn("loopz", "loop", modifiers=[1])
2868add_insn("loope", "loop", modifiers=[1])
2869add_insn("loopnz", "loop", modifiers=[0])
2870add_insn("loopne", "loop", modifiers=[0])
2871
2872# GAS w/l/q suffixes have to set addrsize via modifiers
2873for sfx, sz in zip("wlq", [16, 32, 64]):
2874    add_group("loop"+sfx,
2875        not64=(sz == 16),
2876        only64=(sz == 64),
2877        modifiers=["Gap", "AdSizeR"],
2878        def_opersize_64=64,
2879        opcode=[],
2880        operands=[Operand(type="Imm", dest="JmpRel")])
2881    add_group("loop"+sfx,
2882        not64=(sz == 16),
2883        only64=(sz == 64),
2884        modifiers=["Op0Add", "AdSizeR"],
2885        def_opersize_64=64,
2886        opcode=[0xE0],
2887        operands=[Operand(type="Imm", tmod="Short", dest="JmpRel")])
2888
2889    add_group("loop"+sfx,
2890        not64=(sz == 16),
2891        only64=(sz == 64),
2892        def_opersize_64=64,
2893        opcode=[],
2894        operands=[Operand(type="Imm", dest="JmpRel"),
2895                  Operand(type="Creg", size=sz, dest="AdSizeR")])
2896    add_group("loop"+sfx,
2897        not64=(sz == 16),
2898        only64=(sz == 64),
2899        modifiers=["Op0Add"],
2900        def_opersize_64=64,
2901        opcode=[0xE0],
2902        operands=[Operand(type="Imm", tmod="Short", dest="JmpRel"),
2903                  Operand(type="Creg", size=sz, dest="AdSizeR")])
2904
2905    add_insn("loop"+sfx, "loop"+sfx, parser="gas", modifiers=[2, sz])
2906    add_insn("loopz"+sfx, "loop"+sfx, parser="gas", modifiers=[1, sz])
2907    add_insn("loope"+sfx, "loop"+sfx, parser="gas", modifiers=[1, sz])
2908    add_insn("loopnz"+sfx, "loop"+sfx, parser="gas", modifiers=[0, sz])
2909    add_insn("loopne"+sfx, "loop"+sfx, parser="gas", modifiers=[0, sz])
2910
2911#####################################################################
2912# Set byte on flag instructions
2913#####################################################################
2914add_group("setcc",
2915    suffix="b",
2916    cpu=["386"],
2917    modifiers=["Op1Add"],
2918    opcode=[0x0F, 0x90],
2919    spare=2,
2920    operands=[Operand(type="RM", size=8, relaxed=True, dest="EA")])
2921
2922add_insn("seto", "setcc", modifiers=[0x00])
2923add_insn("setno", "setcc", modifiers=[0x01])
2924add_insn("setb", "setcc", modifiers=[0x02])
2925add_insn("setc", "setcc", modifiers=[0x02])
2926add_insn("setnae", "setcc", modifiers=[0x02])
2927add_insn("setnb", "setcc", modifiers=[0x03])
2928add_insn("setnc", "setcc", modifiers=[0x03])
2929add_insn("setae", "setcc", modifiers=[0x03])
2930add_insn("sete", "setcc", modifiers=[0x04])
2931add_insn("setz", "setcc", modifiers=[0x04])
2932add_insn("setne", "setcc", modifiers=[0x05])
2933add_insn("setnz", "setcc", modifiers=[0x05])
2934add_insn("setbe", "setcc", modifiers=[0x06])
2935add_insn("setna", "setcc", modifiers=[0x06])
2936add_insn("setnbe", "setcc", modifiers=[0x07])
2937add_insn("seta", "setcc", modifiers=[0x07])
2938add_insn("sets", "setcc", modifiers=[0x08])
2939add_insn("setns", "setcc", modifiers=[0x09])
2940add_insn("setp", "setcc", modifiers=[0x0A])
2941add_insn("setpe", "setcc", modifiers=[0x0A])
2942add_insn("setnp", "setcc", modifiers=[0x0B])
2943add_insn("setpo", "setcc", modifiers=[0x0B])
2944add_insn("setl", "setcc", modifiers=[0x0C])
2945add_insn("setnge", "setcc", modifiers=[0x0C])
2946add_insn("setnl", "setcc", modifiers=[0x0D])
2947add_insn("setge", "setcc", modifiers=[0x0D])
2948add_insn("setle", "setcc", modifiers=[0x0E])
2949add_insn("setng", "setcc", modifiers=[0x0E])
2950add_insn("setnle", "setcc", modifiers=[0x0F])
2951add_insn("setg", "setcc", modifiers=[0x0F])
2952
2953#####################################################################
2954# String instructions
2955#####################################################################
2956add_insn("cmpsb", "onebyte", modifiers=[0xA6, 0])
2957add_insn("cmpsw", "onebyte", modifiers=[0xA7, 16])
2958
2959# cmpsd has to be non-onebyte for SSE2 forms below
2960add_group("cmpsd",
2961    parsers=["nasm"],
2962    notavx=True,
2963    opersize=32,
2964    opcode=[0xA7],
2965    operands=[])
2966
2967add_insn("cmpsd", "cmpsd", cpu=[])
2968
2969add_insn("cmpsl", "onebyte", parser="gas", modifiers=[0xA7, 32], cpu=["386"])
2970add_insn("cmpsq", "onebyte", modifiers=[0xA7, 64], only64=True)
2971add_insn("insb", "onebyte", modifiers=[0x6C, 0])
2972add_insn("insw", "onebyte", modifiers=[0x6D, 16])
2973add_insn("insd", "onebyte", parser="nasm", modifiers=[0x6D, 32], cpu=["386"])
2974add_insn("insl", "onebyte", parser="gas", modifiers=[0x6D, 32], cpu=["386"])
2975add_insn("outsb", "onebyte", modifiers=[0x6E, 0])
2976add_insn("outsw", "onebyte", modifiers=[0x6F, 16])
2977add_insn("outsd", "onebyte", parser="nasm", modifiers=[0x6F, 32],
2978         cpu=["386"])
2979add_insn("outsl", "onebyte", parser="gas", modifiers=[0x6F, 32], cpu=["386"])
2980add_insn("lodsb", "onebyte", modifiers=[0xAC, 0])
2981add_insn("lodsw", "onebyte", modifiers=[0xAD, 16])
2982add_insn("lodsd", "onebyte", parser="nasm", modifiers=[0xAD, 32],
2983         cpu=["386"])
2984add_insn("lodsl", "onebyte", parser="gas", modifiers=[0xAD, 32], cpu=["386"])
2985add_insn("lodsq", "onebyte", modifiers=[0xAD, 64], only64=True)
2986add_insn("movsb", "onebyte", modifiers=[0xA4, 0])
2987add_insn("movsw", "onebyte", modifiers=[0xA5, 16])
2988
2989# movsd has to be non-onebyte for SSE2 forms below
2990add_group("movsd",
2991    parsers=["nasm", "gas"],
2992    notavx=True,
2993    opersize=32,
2994    opcode=[0xA5],
2995    operands=[])
2996
2997add_insn("movsd", "movsd", cpu=["386"])
2998
2999add_insn("movsl", "onebyte", parser="gas", modifiers=[0xA5, 32], cpu=["386"])
3000add_insn("movsq", "onebyte", modifiers=[0xA5, 64], only64=True)
3001# smov alias for movs in GAS mode
3002add_insn("smovb", "onebyte", parser="gas", modifiers=[0xA4, 0])
3003add_insn("smovw", "onebyte", parser="gas", modifiers=[0xA5, 16])
3004add_insn("smovl", "onebyte", parser="gas", modifiers=[0xA5, 32], cpu=["386"])
3005add_insn("smovq", "onebyte", parser="gas", modifiers=[0xA5, 64], only64=True)
3006add_insn("scasb", "onebyte", modifiers=[0xAE, 0])
3007add_insn("scasw", "onebyte", modifiers=[0xAF, 16])
3008add_insn("scasd", "onebyte", parser="nasm", modifiers=[0xAF, 32],
3009         cpu=["386"])
3010add_insn("scasl", "onebyte", parser="gas", modifiers=[0xAF, 32], cpu=["386"])
3011add_insn("scasq", "onebyte", modifiers=[0xAF, 64], only64=True)
3012# ssca alias for scas in GAS mode
3013add_insn("sscab", "onebyte", parser="gas", modifiers=[0xAE, 0])
3014add_insn("sscaw", "onebyte", parser="gas", modifiers=[0xAF, 16])
3015add_insn("sscal", "onebyte", parser="gas", modifiers=[0xAF, 32], cpu=["386"])
3016add_insn("sscaq", "onebyte", parser="gas", modifiers=[0xAF, 64], only64=True)
3017add_insn("stosb", "onebyte", modifiers=[0xAA, 0])
3018add_insn("stosw", "onebyte", modifiers=[0xAB, 16])
3019add_insn("stosd", "onebyte", parser="nasm", modifiers=[0xAB, 32],
3020         cpu=["386"])
3021add_insn("stosl", "onebyte", parser="gas", modifiers=[0xAB, 32], cpu=["386"])
3022add_insn("stosq", "onebyte", modifiers=[0xAB, 64], only64=True)
3023add_insn("xlatb", "onebyte", modifiers=[0xD7, 0])
3024
3025#####################################################################
3026# Bit manipulation
3027#####################################################################
3028
3029#
3030# bit tests
3031#
3032for sfx, sz in zip("wlq", [16, 32, 64]):
3033    add_group("bittest",
3034        suffix=sfx,
3035        cpu=["386"],
3036        modifiers=["Op1Add"],
3037        opersize=sz,
3038        opcode=[0x0F, 0x00],
3039        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
3040                  Operand(type="Reg", size=sz, dest="Spare")])
3041for sfx, sz in zip("wlq", [16, 32, 64]):
3042    add_group("bittest",
3043        suffix=sfx,
3044        cpu=["386"],
3045        modifiers=["Gap", "SpAdd"],
3046        opersize=sz,
3047        opcode=[0x0F, 0xBA],
3048        spare=0,
3049        operands=[Operand(type="RM", size=sz, dest="EA"),
3050                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
3051
3052add_insn("bt",  "bittest", modifiers=[0xA3, 4])
3053add_insn("bts", "bittest", modifiers=[0xAB, 5])
3054add_insn("btr", "bittest", modifiers=[0xB3, 6])
3055add_insn("btc", "bittest", modifiers=[0xBB, 7])
3056
3057#
3058# bit scans - also used for lar/lsl
3059#
3060for sfx, sz in zip("wlq", [16, 32, 64]):
3061    add_group("bsfr",
3062        suffix=sfx,
3063        modifiers=["Op1Add"],
3064        opersize=sz,
3065        opcode=[0x0F, 0x00],
3066        operands=[Operand(type="Reg", size=sz, dest="Spare"),
3067                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
3068
3069add_insn("bsf", "bsfr", modifiers=[0xBC], cpu=["386"])
3070add_insn("bsr", "bsfr", modifiers=[0xBD], cpu=["386"])
3071
3072#####################################################################
3073# Interrupts and operating system instructions
3074#####################################################################
3075add_group("int",
3076    opcode=[0xCD],
3077    operands=[Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
3078
3079add_insn("int", "int")
3080add_insn("int3", "onebyte", modifiers=[0xCC])
3081add_insn("int03", "onebyte", parser="nasm", modifiers=[0xCC])
3082add_insn("into", "onebyte", modifiers=[0xCE], not64=True)
3083add_insn("iret", "onebyte", modifiers=[0xCF])
3084add_insn("iretw", "onebyte", modifiers=[0xCF, 16])
3085add_insn("iretd", "onebyte", parser="nasm", modifiers=[0xCF, 32],
3086         cpu=["386"])
3087add_insn("iretl", "onebyte", parser="gas", modifiers=[0xCF, 32], cpu=["386"])
3088add_insn("iretq", "onebyte", modifiers=[0xCF, 64], only64=True)
3089add_insn("rsm", "twobyte", modifiers=[0x0F, 0xAA], cpu=["586", "SMM"])
3090
3091for sfx, sz in zip("wl", [16, 32]):
3092    add_group("bound",
3093        suffix=sfx,
3094        cpu=["186"],
3095        not64=True,
3096        opersize=sz,
3097        opcode=[0x62],
3098        operands=[Operand(type="Reg", size=sz, dest="Spare"),
3099                  Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
3100
3101add_insn("bound", "bound")
3102add_insn("hlt", "onebyte", modifiers=[0xF4], cpu=["Priv"])
3103add_insn("nop", "onebyte", modifiers=[0x90])
3104
3105#
3106# Protection control
3107#
3108for sfx, sz, sz2 in zip("wlq", [16, 32, 64], [16, 32, 32]):
3109    add_group("larlsl",
3110        suffix=sfx,
3111        modifiers=["Op1Add"],
3112        opersize=sz,
3113        opcode=[0x0F, 0x00],
3114        operands=[Operand(type="Reg", size=sz, dest="Spare"),
3115                  Operand(type="Reg", size=sz2, dest="EA")])
3116    add_group("larlsl",
3117        suffix=sfx,
3118        modifiers=["Op1Add"],
3119        opersize=sz,
3120        opcode=[0x0F, 0x00],
3121        operands=[Operand(type="Reg", size=sz, dest="Spare"),
3122                  Operand(type="RM", size=16, relaxed=True, dest="EA")])
3123
3124add_insn("lar", "larlsl", modifiers=[0x02], cpu=["286", "Prot"])
3125add_insn("lsl", "larlsl", modifiers=[0x03], cpu=["286", "Prot"])
3126
3127add_group("arpl",
3128    suffix="w",
3129    cpu=["Prot", "286"],
3130    not64=True,
3131    opcode=[0x63],
3132    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA"),
3133              Operand(type="Reg", size=16, dest="Spare")])
3134
3135add_insn("arpl", "arpl")
3136
3137for sfx in [None, "w", "l", "q"]:
3138    add_insn("lgdt"+(sfx or ""), "twobytemem", suffix=sfx,
3139             modifiers=[2, 0x0F, 0x01], cpu=["286", "Priv"])
3140    add_insn("lidt"+(sfx or ""), "twobytemem", suffix=sfx,
3141             modifiers=[3, 0x0F, 0x01], cpu=["286", "Priv"])
3142    add_insn("sgdt"+(sfx or ""), "twobytemem", suffix=sfx,
3143             modifiers=[0, 0x0F, 0x01], cpu=["286", "Priv"])
3144    add_insn("sidt"+(sfx or ""), "twobytemem", suffix=sfx,
3145             modifiers=[1, 0x0F, 0x01], cpu=["286", "Priv"])
3146
3147for sfx, sz in zip("wlq", [16, 32, 64]):
3148    add_group("str",
3149        suffix=sfx,
3150        cpu=["Prot", "286"],
3151        opersize=sz,
3152        opcode=[0x0F, 0x00],
3153        spare=1,
3154        operands=[Operand(type="Reg", size=sz, dest="EA")])
3155add_group("str",
3156    suffixes=["w", "l"],
3157    cpu=["Prot", "286"],
3158    opcode=[0x0F, 0x00],
3159    spare=1,
3160    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA")])
3161
3162add_insn("str", "str")
3163
3164add_group("prot286",
3165    suffix="w",
3166    cpu=["286"],
3167    modifiers=["SpAdd", "Op1Add"],
3168    opcode=[0x0F, 0x00],
3169    spare=0,
3170    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA")])
3171
3172add_insn("lldt", "prot286", modifiers=[2, 0], cpu=["286", "Prot", "Priv"])
3173add_insn("ltr", "prot286", modifiers=[3, 0], cpu=["286", "Prot", "Priv"])
3174add_insn("verr", "prot286", modifiers=[4, 0], cpu=["286", "Prot"])
3175add_insn("verw", "prot286", modifiers=[5, 0], cpu=["286", "Prot"])
3176add_insn("lmsw", "prot286", modifiers=[6, 1], cpu=["286", "Priv"])
3177
3178for sfx, sz in zip("wlq", [16, 32, 64]):
3179    add_group("sldtmsw",
3180        suffix=sfx,
3181        only64=(sz==64),
3182        cpu=[(sz==32) and "386" or "286"],
3183        modifiers=["SpAdd", "Op1Add"],
3184        opcode=[0x0F, 0x00],
3185        spare=0,
3186        operands=[Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
3187for sfx, sz in zip("wlq", [16, 32, 64]):
3188    add_group("sldtmsw",
3189        suffix=sfx,
3190        cpu=["286"],
3191        modifiers=["SpAdd", "Op1Add"],
3192        opersize=sz,
3193        opcode=[0x0F, 0x00],
3194        spare=0,
3195        operands=[Operand(type="Reg", size=sz, dest="EA")])
3196
3197add_insn("sldt", "sldtmsw", modifiers=[0, 0])
3198add_insn("smsw", "sldtmsw", modifiers=[4, 1])
3199
3200#####################################################################
3201# Floating point instructions
3202#####################################################################
3203add_insn("fcompp",  "twobyte", modifiers=[0xDE, 0xD9], cpu=["FPU"])
3204add_insn("fucompp", "twobyte", modifiers=[0xDA, 0xE9], cpu=["286", "FPU"])
3205add_insn("ftst",    "twobyte", modifiers=[0xD9, 0xE4], cpu=["FPU"])
3206add_insn("fxam",    "twobyte", modifiers=[0xD9, 0xE5], cpu=["FPU"])
3207add_insn("fld1",    "twobyte", modifiers=[0xD9, 0xE8], cpu=["FPU"])
3208add_insn("fldl2t",  "twobyte", modifiers=[0xD9, 0xE9], cpu=["FPU"])
3209add_insn("fldl2e",  "twobyte", modifiers=[0xD9, 0xEA], cpu=["FPU"])
3210add_insn("fldpi",   "twobyte", modifiers=[0xD9, 0xEB], cpu=["FPU"])
3211add_insn("fldlg2",  "twobyte", modifiers=[0xD9, 0xEC], cpu=["FPU"])
3212add_insn("fldln2",  "twobyte", modifiers=[0xD9, 0xED], cpu=["FPU"])
3213add_insn("fldz",    "twobyte", modifiers=[0xD9, 0xEE], cpu=["FPU"])
3214add_insn("f2xm1",   "twobyte", modifiers=[0xD9, 0xF0], cpu=["FPU"])
3215add_insn("fyl2x",   "twobyte", modifiers=[0xD9, 0xF1], cpu=["FPU"])
3216add_insn("fptan",   "twobyte", modifiers=[0xD9, 0xF2], cpu=["FPU"])
3217add_insn("fpatan",  "twobyte", modifiers=[0xD9, 0xF3], cpu=["FPU"])
3218add_insn("fxtract", "twobyte", modifiers=[0xD9, 0xF4], cpu=["FPU"])
3219add_insn("fprem1",  "twobyte", modifiers=[0xD9, 0xF5], cpu=["286", "FPU"])
3220add_insn("fdecstp", "twobyte", modifiers=[0xD9, 0xF6], cpu=["FPU"])
3221add_insn("fincstp", "twobyte", modifiers=[0xD9, 0xF7], cpu=["FPU"])
3222add_insn("fprem",   "twobyte", modifiers=[0xD9, 0xF8], cpu=["FPU"])
3223add_insn("fyl2xp1", "twobyte", modifiers=[0xD9, 0xF9], cpu=["FPU"])
3224add_insn("fsqrt",   "twobyte", modifiers=[0xD9, 0xFA], cpu=["FPU"])
3225add_insn("fsincos", "twobyte", modifiers=[0xD9, 0xFB], cpu=["286", "FPU"])
3226add_insn("frndint", "twobyte", modifiers=[0xD9, 0xFC], cpu=["FPU"])
3227add_insn("fscale",  "twobyte", modifiers=[0xD9, 0xFD], cpu=["FPU"])
3228add_insn("fsin",    "twobyte", modifiers=[0xD9, 0xFE], cpu=["286", "FPU"])
3229add_insn("fcos",    "twobyte", modifiers=[0xD9, 0xFF], cpu=["286", "FPU"])
3230add_insn("fchs",    "twobyte", modifiers=[0xD9, 0xE0], cpu=["FPU"])
3231add_insn("fabs",    "twobyte", modifiers=[0xD9, 0xE1], cpu=["FPU"])
3232add_insn("fninit",  "twobyte", modifiers=[0xDB, 0xE3], cpu=["FPU"])
3233add_insn("finit", "threebyte", modifiers=[0x9B, 0xDB, 0xE3], cpu=["FPU"])
3234add_insn("fnclex",  "twobyte", modifiers=[0xDB, 0xE2], cpu=["FPU"])
3235add_insn("fclex", "threebyte", modifiers=[0x9B, 0xDB, 0xE2], cpu=["FPU"])
3236for sfx in [None, "l", "s"]:
3237    add_insn("fnstenv"+(sfx or ""), "onebytemem", suffix=sfx,
3238             modifiers=[6, 0xD9], cpu=["FPU"])
3239    add_insn("fstenv"+(sfx or ""),  "twobytemem", suffix=sfx,
3240             modifiers=[6, 0x9B, 0xD9], cpu=["FPU"])
3241    add_insn("fldenv"+(sfx or ""),  "onebytemem", suffix=sfx,
3242             modifiers=[4, 0xD9], cpu=["FPU"])
3243    add_insn("fnsave"+(sfx or ""),  "onebytemem", suffix=sfx,
3244             modifiers=[6, 0xDD], cpu=["FPU"])
3245    add_insn("fsave"+(sfx or ""),   "twobytemem", suffix=sfx,
3246             modifiers=[6, 0x9B, 0xDD], cpu=["FPU"])
3247    add_insn("frstor"+(sfx or ""),  "onebytemem", suffix=sfx,
3248             modifiers=[4, 0xDD], cpu=["FPU"])
3249add_insn("fnop",    "twobyte", modifiers=[0xD9, 0xD0], cpu=["FPU"])
3250add_insn("fwait",   "onebyte", modifiers=[0x9B], cpu=["FPU"])
3251# Prefixes; should the others be here too? should wait be a prefix?
3252add_insn("wait",    "onebyte", modifiers=[0x9B])
3253
3254#
3255# load/store with pop (integer and normal)
3256#
3257add_group("fld",
3258    suffix="s",
3259    cpu=["FPU"],
3260    opcode=[0xD9],
3261    operands=[Operand(type="Mem", size=32, dest="EA")])
3262add_group("fld",
3263    suffix="l",
3264    cpu=["FPU"],
3265    opcode=[0xDD],
3266    operands=[Operand(type="Mem", size=64, dest="EA")])
3267add_group("fld",
3268    cpu=["FPU"],
3269    opcode=[0xDB],
3270    spare=5,
3271    operands=[Operand(type="Mem", size=80, dest="EA")])
3272add_group("fld",
3273    cpu=["FPU"],
3274    opcode=[0xD9, 0xC0],
3275    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3276
3277add_insn("fld", "fld")
3278
3279add_group("fstp",
3280    suffix="s",
3281    cpu=["FPU"],
3282    opcode=[0xD9],
3283    spare=3,
3284    operands=[Operand(type="Mem", size=32, dest="EA")])
3285add_group("fstp",
3286    suffix="l",
3287    cpu=["FPU"],
3288    opcode=[0xDD],
3289    spare=3,
3290    operands=[Operand(type="Mem", size=64, dest="EA")])
3291add_group("fstp",
3292    cpu=["FPU"],
3293    opcode=[0xDB],
3294    spare=7,
3295    operands=[Operand(type="Mem", size=80, dest="EA")])
3296add_group("fstp",
3297    cpu=["FPU"],
3298    opcode=[0xDD, 0xD8],
3299    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3300
3301add_insn("fstp", "fstp")
3302
3303#
3304# Long memory version of floating point load/store for GAS
3305#
3306add_group("fldstpt",
3307    cpu=["FPU"],
3308    modifiers=["SpAdd"],
3309    opcode=[0xDB],
3310    spare=0,
3311    operands=[Operand(type="Mem", size=80, relaxed=True, dest="EA")])
3312
3313add_insn("fldt", "fldstpt", modifiers=[5])
3314add_insn("fstpt", "fldstpt", modifiers=[7])
3315
3316add_group("fildstp",
3317    suffix="s",
3318    cpu=["FPU"],
3319    modifiers=["SpAdd"],
3320    opcode=[0xDF],
3321    spare=0,
3322    operands=[Operand(type="Mem", size=16, dest="EA")])
3323add_group("fildstp",
3324    suffix="l",
3325    cpu=["FPU"],
3326    modifiers=["SpAdd"],
3327    opcode=[0xDB],
3328    spare=0,
3329    operands=[Operand(type="Mem", size=32, dest="EA")])
3330add_group("fildstp",
3331    suffix="q",
3332    cpu=["FPU"],
3333    modifiers=["Gap", "Op0Add", "SpAdd"],
3334    opcode=[0xDD],
3335    spare=0,
3336    operands=[Operand(type="Mem", size=64, dest="EA")])
3337# No-suffix alias for memory for GAS compat -> "s" version generated
3338add_group("fildstp",
3339    cpu=["FPU"],
3340    parsers=["gas"],
3341    modifiers=["SpAdd"],
3342    opcode=[0xDF],
3343    spare=0,
3344    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA")])
3345
3346add_insn("fild", "fildstp", modifiers=[0, 2, 5])
3347add_insn("fistp", "fildstp", modifiers=[3, 2, 7])
3348
3349add_group("fbldstp",
3350    cpu=["FPU"],
3351    modifiers=["SpAdd"],
3352    opcode=[0xDF],
3353    spare=0,
3354    operands=[Operand(type="Mem", size=80, relaxed=True, dest="EA")])
3355
3356add_insn("fbld", "fbldstp", modifiers=[4])
3357add_insn("fildll", "fbldstp", parser="gas", modifiers=[5])
3358add_insn("fbstp", "fbldstp", modifiers=[6])
3359add_insn("fistpll", "fbldstp", parser="gas", modifiers=[7])
3360
3361#
3362# store (normal)
3363#
3364add_group("fst",
3365    suffix="s",
3366    cpu=["FPU"],
3367    opcode=[0xD9],
3368    spare=2,
3369    operands=[Operand(type="Mem", size=32, dest="EA")])
3370add_group("fst",
3371    suffix="l",
3372    cpu=["FPU"],
3373    opcode=[0xDD],
3374    spare=2,
3375    operands=[Operand(type="Mem", size=64, dest="EA")])
3376add_group("fst",
3377    cpu=["FPU"],
3378    opcode=[0xDD, 0xD0],
3379    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3380
3381add_insn("fst", "fst")
3382
3383#
3384# exchange (with ST0)
3385#
3386add_group("fxch",
3387    cpu=["FPU"],
3388    opcode=[0xD9, 0xC8],
3389    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3390add_group("fxch",
3391    cpu=["FPU"],
3392    opcode=[0xD9, 0xC8],
3393    operands=[Operand(type="ST0", size=80, dest=None),
3394              Operand(type="Reg", size=80, dest="Op1Add")])
3395add_group("fxch",
3396    cpu=["FPU"],
3397    opcode=[0xD9, 0xC8],
3398    operands=[Operand(type="Reg", size=80, dest="Op1Add"),
3399              Operand(type="ST0", size=80, dest=None)])
3400add_group("fxch",
3401    cpu=["FPU"],
3402    opcode=[0xD9, 0xC9],
3403    operands=[])
3404
3405add_insn("fxch", "fxch")
3406
3407#
3408# comparisons
3409#
3410add_group("fcom",
3411    suffix="s",
3412    cpu=["FPU"],
3413    modifiers=["Gap", "SpAdd"],
3414    opcode=[0xD8],
3415    spare=0,
3416    operands=[Operand(type="Mem", size=32, dest="EA")])
3417add_group("fcom",
3418    suffix="l",
3419    cpu=["FPU"],
3420    modifiers=["Gap", "SpAdd"],
3421    opcode=[0xDC],
3422    spare=0,
3423    operands=[Operand(type="Mem", size=64, dest="EA")])
3424add_group("fcom",
3425    cpu=["FPU"],
3426    modifiers=["Op1Add"],
3427    opcode=[0xD8, 0x00],
3428    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3429# No-suffix alias for memory for GAS compat -> "s" version generated
3430add_group("fcom",
3431    cpu=["FPU"],
3432    parsers=["gas"],
3433    modifiers=["Gap", "SpAdd"],
3434    opcode=[0xD8],
3435    spare=0,
3436    operands=[Operand(type="Mem", size=32, relaxed=True, dest="EA")])
3437# Alias for fcom %st(1) for GAS compat
3438add_group("fcom",
3439    cpu=["FPU"],
3440    parsers=["gas"],
3441    modifiers=["Op1Add"],
3442    opcode=[0xD8, 0x01],
3443    operands=[])
3444add_group("fcom",
3445    cpu=["FPU"],
3446    parsers=["nasm"],
3447    modifiers=["Op1Add"],
3448    opcode=[0xD8, 0x00],
3449    operands=[Operand(type="ST0", size=80, dest=None),
3450              Operand(type="Reg", size=80, dest="Op1Add")])
3451
3452add_insn("fcom", "fcom", modifiers=[0xD0, 2])
3453add_insn("fcomp", "fcom", modifiers=[0xD8, 3])
3454
3455#
3456# extended comparisons
3457#
3458add_group("fcom2",
3459    cpu=["FPU", "286"],
3460    modifiers=["Op0Add", "Op1Add"],
3461    opcode=[0x00, 0x00],
3462    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3463add_group("fcom2",
3464    cpu=["FPU", "286"],
3465    modifiers=["Op0Add", "Op1Add"],
3466    opcode=[0x00, 0x00],
3467    operands=[Operand(type="ST0", size=80, dest=None),
3468              Operand(type="Reg", size=80, dest="Op1Add")])
3469
3470add_insn("fucom", "fcom2", modifiers=[0xDD, 0xE0])
3471add_insn("fucomp", "fcom2", modifiers=[0xDD, 0xE8])
3472
3473#
3474# arithmetic
3475#
3476add_group("farith",
3477    suffix="s",
3478    cpu=["FPU"],
3479    modifiers=["Gap", "Gap", "SpAdd"],
3480    opcode=[0xD8],
3481    spare=0,
3482    operands=[Operand(type="Mem", size=32, dest="EA")])
3483add_group("farith",
3484    suffix="l",
3485    cpu=["FPU"],
3486    modifiers=["Gap", "Gap", "SpAdd"],
3487    opcode=[0xDC],
3488    spare=0,
3489    operands=[Operand(type="Mem", size=64, dest="EA")])
3490add_group("farith",
3491    cpu=["FPU"],
3492    modifiers=["Gap", "Op1Add"],
3493    opcode=[0xD8, 0x00],
3494    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3495add_group("farith",
3496    cpu=["FPU"],
3497    modifiers=["Gap", "Op1Add"],
3498    opcode=[0xD8, 0x00],
3499    operands=[Operand(type="ST0", size=80, dest=None),
3500              Operand(type="Reg", size=80, dest="Op1Add")])
3501add_group("farith",
3502    cpu=["FPU"],
3503    modifiers=["Op1Add"],
3504    opcode=[0xDC, 0x00],
3505    operands=[Operand(type="Reg", size=80, tmod="To", dest="Op1Add")])
3506add_group("farith",
3507    cpu=["FPU"],
3508    parsers=["nasm"],
3509    modifiers=["Op1Add"],
3510    opcode=[0xDC, 0x00],
3511    operands=[Operand(type="Reg", size=80, dest="Op1Add"),
3512              Operand(type="ST0", size=80, dest=None)])
3513add_group("farith",
3514    cpu=["FPU"],
3515    parsers=["gas"],
3516    modifiers=["Gap", "Op1Add"],
3517    opcode=[0xDC, 0x00],
3518    operands=[Operand(type="Reg", size=80, dest="Op1Add"),
3519              Operand(type="ST0", size=80, dest=None)])
3520
3521add_insn("fadd", "farith", modifiers=[0xC0, 0xC0, 0])
3522add_insn("fsub", "farith", modifiers=[0xE8, 0xE0, 4])
3523add_insn("fsubr", "farith", modifiers=[0xE0, 0xE8, 5])
3524add_insn("fmul", "farith", modifiers=[0xC8, 0xC8, 1])
3525add_insn("fdiv", "farith", modifiers=[0xF8, 0xF0, 6])
3526add_insn("fdivr", "farith", modifiers=[0xF0, 0xF8, 7])
3527
3528add_group("farithp",
3529    cpu=["FPU"],
3530    modifiers=["Op1Add"],
3531    opcode=[0xDE, 0x01],
3532    operands=[])
3533add_group("farithp",
3534    cpu=["FPU"],
3535    modifiers=["Op1Add"],
3536    opcode=[0xDE, 0x00],
3537    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3538add_group("farithp",
3539    cpu=["FPU"],
3540    modifiers=["Op1Add"],
3541    opcode=[0xDE, 0x00],
3542    operands=[Operand(type="Reg", size=80, dest="Op1Add"),
3543              Operand(type="ST0", size=80, dest=None)])
3544
3545add_insn("faddp", "farithp", modifiers=[0xC0])
3546add_insn("fsubp", "farithp", parser="nasm", modifiers=[0xE8])
3547add_insn("fsubp", "farithp", parser="gas", modifiers=[0xE0])
3548add_insn("fsubrp", "farithp", parser="nasm", modifiers=[0xE0])
3549add_insn("fsubrp", "farithp", parser="gas", modifiers=[0xE8])
3550add_insn("fmulp", "farithp", modifiers=[0xC8])
3551add_insn("fdivp", "farithp", parser="nasm", modifiers=[0xF8])
3552add_insn("fdivp", "farithp", parser="gas", modifiers=[0xF0])
3553add_insn("fdivrp", "farithp", parser="nasm", modifiers=[0xF0])
3554add_insn("fdivrp", "farithp", parser="gas", modifiers=[0xF8])
3555
3556#
3557# integer arith/store wo pop/compare
3558#
3559add_group("fiarith",
3560    suffix="s",
3561    cpu=["FPU"],
3562    modifiers=["SpAdd", "Op0Add"],
3563    opcode=[0x04],
3564    spare=0,
3565    operands=[Operand(type="Mem", size=16, dest="EA")])
3566add_group("fiarith",
3567    suffix="l",
3568    cpu=["FPU"],
3569    modifiers=["SpAdd", "Op0Add"],
3570    opcode=[0x00],
3571    spare=0,
3572    operands=[Operand(type="Mem", size=32, dest="EA")])
3573
3574add_insn("fist",   "fiarith", modifiers=[2, 0xDB])
3575add_insn("ficom",  "fiarith", modifiers=[2, 0xDA])
3576add_insn("ficomp", "fiarith", modifiers=[3, 0xDA])
3577add_insn("fiadd",  "fiarith", modifiers=[0, 0xDA])
3578add_insn("fisub",  "fiarith", modifiers=[4, 0xDA])
3579add_insn("fisubr", "fiarith", modifiers=[5, 0xDA])
3580add_insn("fimul",  "fiarith", modifiers=[1, 0xDA])
3581add_insn("fidiv",  "fiarith", modifiers=[6, 0xDA])
3582add_insn("fidivr", "fiarith", modifiers=[7, 0xDA])
3583
3584#
3585# processor control
3586#
3587add_group("fldnstcw",
3588    suffix="w",
3589    cpu=["FPU"],
3590    modifiers=["SpAdd"],
3591    opcode=[0xD9],
3592    spare=0,
3593    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA")])
3594
3595add_insn("fldcw", "fldnstcw", modifiers=[5])
3596add_insn("fnstcw", "fldnstcw", modifiers=[7])
3597
3598add_group("fstcw",
3599    suffix="w",
3600    cpu=["FPU"],
3601    opcode=[0x9B, 0xD9],
3602    spare=7,
3603    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA")])
3604
3605add_insn("fstcw", "fstcw")
3606
3607add_group("fnstsw",
3608    suffix="w",
3609    cpu=["FPU"],
3610    opcode=[0xDD],
3611    spare=7,
3612    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA")])
3613add_group("fnstsw",
3614    suffix="w",
3615    cpu=["FPU"],
3616    opcode=[0xDF, 0xE0],
3617    operands=[Operand(type="Areg", size=16, dest=None)])
3618
3619add_insn("fnstsw", "fnstsw")
3620
3621add_group("fstsw",
3622    suffix="w",
3623    cpu=["FPU"],
3624    opcode=[0x9B, 0xDD],
3625    spare=7,
3626    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA")])
3627add_group("fstsw",
3628    suffix="w",
3629    cpu=["FPU"],
3630    opcode=[0x9B, 0xDF, 0xE0],
3631    operands=[Operand(type="Areg", size=16, dest=None)])
3632
3633add_insn("fstsw", "fstsw")
3634
3635add_group("ffree",
3636    cpu=["FPU"],
3637    modifiers=["Op0Add"],
3638    opcode=[0x00, 0xC0],
3639    operands=[Operand(type="Reg", size=80, dest="Op1Add")])
3640
3641add_insn("ffree", "ffree", modifiers=[0xDD])
3642add_insn("ffreep", "ffree", modifiers=[0xDF], cpu=["686", "FPU", "Undoc"])
3643
3644#####################################################################
3645# 486 extensions
3646#####################################################################
3647add_group("bswap",
3648    suffix="l",
3649    cpu=["486"],
3650    opersize=32,
3651    opcode=[0x0F, 0xC8],
3652    operands=[Operand(type="Reg", size=32, dest="Op1Add")])
3653add_group("bswap",
3654    suffix="q",
3655    opersize=64,
3656    opcode=[0x0F, 0xC8],
3657    operands=[Operand(type="Reg", size=64, dest="Op1Add")])
3658
3659add_insn("bswap", "bswap")
3660
3661for sfx, sz in zip("bwlq", [8, 16, 32, 64]):
3662    add_group("cmpxchgxadd",
3663        suffix=sfx,
3664        cpu=["486"],
3665        modifiers=["Op1Add"],
3666        opersize=sz,
3667        opcode=[0x0F, 0x00+(sz!=8)],
3668        operands=[Operand(type="RM", size=sz, relaxed=True, dest="EA"),
3669                  Operand(type="Reg", size=sz, dest="Spare")])
3670
3671add_insn("xadd", "cmpxchgxadd", modifiers=[0xC0])
3672add_insn("cmpxchg", "cmpxchgxadd", modifiers=[0xB0])
3673add_insn("cmpxchg486", "cmpxchgxadd", parser="nasm", modifiers=[0xA6],
3674         cpu=["486", "Undoc"])
3675
3676add_insn("invd", "twobyte", modifiers=[0x0F, 0x08], cpu=["486", "Priv"])
3677add_insn("wbinvd", "twobyte", modifiers=[0x0F, 0x09], cpu=["486", "Priv"])
3678add_insn("invlpg", "twobytemem", modifiers=[7, 0x0F, 0x01],
3679         cpu=["486", "Priv"])
3680
3681#####################################################################
3682# 586+ and late 486 extensions
3683#####################################################################
3684add_insn("cpuid", "twobyte", modifiers=[0x0F, 0xA2], cpu=["486"])
3685
3686#####################################################################
3687# Pentium extensions
3688#####################################################################
3689add_insn("wrmsr", "twobyte", modifiers=[0x0F, 0x30], cpu=["586", "Priv"])
3690add_insn("rdtsc", "twobyte", modifiers=[0x0F, 0x31], cpu=["586"])
3691add_insn("rdmsr", "twobyte", modifiers=[0x0F, 0x32], cpu=["586", "Priv"])
3692
3693add_group("cmpxchg8b",
3694    suffix="q",
3695    cpu=["586"],
3696    opcode=[0x0F, 0xC7],
3697    spare=1,
3698    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA")])
3699
3700add_insn("cmpxchg8b", "cmpxchg8b")
3701
3702#####################################################################
3703# Pentium II/Pentium Pro extensions
3704#####################################################################
3705add_insn("sysenter", "twobyte", modifiers=[0x0F, 0x34], cpu=["686"],
3706         not64=True)
3707add_insn("sysexit",  "twobyte", modifiers=[0x0F, 0x35], cpu=["686", "Priv"],
3708         not64=True)
3709for sfx in [None, "q"]:
3710    add_insn("fxsave"+(sfx or ""),  "twobytemem", suffix=sfx,
3711             modifiers=[0, 0x0F, 0xAE], cpu=["686", "FPU"])
3712    add_insn("fxrstor"+(sfx or ""), "twobytemem", suffix=sfx,
3713             modifiers=[1, 0x0F, 0xAE], cpu=["686", "FPU"])
3714add_insn("rdpmc", "twobyte", modifiers=[0x0F, 0x33], cpu=["686"])
3715add_insn("ud2",   "twobyte", modifiers=[0x0F, 0x0B], cpu=["286"])
3716add_insn("ud1",   "twobyte", modifiers=[0x0F, 0xB9], cpu=["286", "Undoc"])
3717
3718for sfx, sz in zip("wlq", [16, 32, 64]):
3719    add_group("cmovcc",
3720        suffix=sfx,
3721        cpu=["686"],
3722        modifiers=["Op1Add"],
3723        opersize=sz,
3724        opcode=[0x0F, 0x40],
3725        operands=[Operand(type="Reg", size=sz, dest="Spare"),
3726                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
3727
3728add_insn("cmovo", "cmovcc", modifiers=[0x00])
3729add_insn("cmovno", "cmovcc", modifiers=[0x01])
3730add_insn("cmovb", "cmovcc", modifiers=[0x02])
3731add_insn("cmovc", "cmovcc", modifiers=[0x02])
3732add_insn("cmovnae", "cmovcc", modifiers=[0x02])
3733add_insn("cmovnb", "cmovcc", modifiers=[0x03])
3734add_insn("cmovnc", "cmovcc", modifiers=[0x03])
3735add_insn("cmovae", "cmovcc", modifiers=[0x03])
3736add_insn("cmove", "cmovcc", modifiers=[0x04])
3737add_insn("cmovz", "cmovcc", modifiers=[0x04])
3738add_insn("cmovne", "cmovcc", modifiers=[0x05])
3739add_insn("cmovnz", "cmovcc", modifiers=[0x05])
3740add_insn("cmovbe", "cmovcc", modifiers=[0x06])
3741add_insn("cmovna", "cmovcc", modifiers=[0x06])
3742add_insn("cmovnbe", "cmovcc", modifiers=[0x07])
3743add_insn("cmova", "cmovcc", modifiers=[0x07])
3744add_insn("cmovs", "cmovcc", modifiers=[0x08])
3745add_insn("cmovns", "cmovcc", modifiers=[0x09])
3746add_insn("cmovp", "cmovcc", modifiers=[0x0A])
3747add_insn("cmovpe", "cmovcc", modifiers=[0x0A])
3748add_insn("cmovnp", "cmovcc", modifiers=[0x0B])
3749add_insn("cmovpo", "cmovcc", modifiers=[0x0B])
3750add_insn("cmovl", "cmovcc", modifiers=[0x0C])
3751add_insn("cmovnge", "cmovcc", modifiers=[0x0C])
3752add_insn("cmovnl", "cmovcc", modifiers=[0x0D])
3753add_insn("cmovge", "cmovcc", modifiers=[0x0D])
3754add_insn("cmovle", "cmovcc", modifiers=[0x0E])
3755add_insn("cmovng", "cmovcc", modifiers=[0x0E])
3756add_insn("cmovnle", "cmovcc", modifiers=[0x0F])
3757add_insn("cmovg", "cmovcc", modifiers=[0x0F])
3758
3759add_group("fcmovcc",
3760    cpu=["FPU", "686"],
3761    modifiers=["Op0Add", "Op1Add"],
3762    opcode=[0x00, 0x00],
3763    operands=[Operand(type="ST0", size=80, dest=None),
3764              Operand(type="Reg", size=80, dest="Op1Add")])
3765
3766add_insn("fcmovb",   "fcmovcc", modifiers=[0xDA, 0xC0])
3767add_insn("fcmove",   "fcmovcc", modifiers=[0xDA, 0xC8])
3768add_insn("fcmovbe",  "fcmovcc", modifiers=[0xDA, 0xD0])
3769add_insn("fcmovu",   "fcmovcc", modifiers=[0xDA, 0xD8])
3770add_insn("fcmovnb",  "fcmovcc", modifiers=[0xDB, 0xC0])
3771add_insn("fcmovne",  "fcmovcc", modifiers=[0xDB, 0xC8])
3772add_insn("fcmovnbe", "fcmovcc", modifiers=[0xDB, 0xD0])
3773add_insn("fcmovnu",  "fcmovcc", modifiers=[0xDB, 0xD8])
3774
3775add_insn("fcomi", "fcom2", modifiers=[0xDB, 0xF0], cpu=["686", "FPU"])
3776add_insn("fucomi", "fcom2", modifiers=[0xDB, 0xE8], cpu=["686", "FPU"])
3777add_insn("fcomip", "fcom2", modifiers=[0xDF, 0xF0], cpu=["686", "FPU"])
3778add_insn("fucomip", "fcom2", modifiers=[0xDF, 0xE8], cpu=["686", "FPU"])
3779
3780#####################################################################
3781# Pentium4 extensions
3782#####################################################################
3783add_group("movnti",
3784    suffix="l",
3785    cpu=["P4"],
3786    opcode=[0x0F, 0xC3],
3787    operands=[Operand(type="Mem", size=32, relaxed=True, dest="EA"),
3788              Operand(type="Reg", size=32, dest="Spare")])
3789add_group("movnti",
3790    suffix="q",
3791    cpu=["P4"],
3792    opersize=64,
3793    opcode=[0x0F, 0xC3],
3794    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
3795              Operand(type="Reg", size=64, dest="Spare")])
3796
3797add_insn("movnti", "movnti")
3798
3799add_group("clflush",
3800    cpu=["P3"],
3801    opcode=[0x0F, 0xAE],
3802    spare=7,
3803    operands=[Operand(type="Mem", size=8, relaxed=True, dest="EA")])
3804
3805add_insn("clflush", "clflush")
3806
3807add_insn("lfence", "threebyte", modifiers=[0x0F, 0xAE, 0xE8], cpu=["P3"])
3808add_insn("mfence", "threebyte", modifiers=[0x0F, 0xAE, 0xF0], cpu=["P3"])
3809add_insn("pause", "onebyte_prefix", modifiers=[0xF3, 0x90], cpu=["P4"])
3810
3811#####################################################################
3812# MMX/SSE2 instructions
3813#####################################################################
3814
3815add_insn("emms", "twobyte", modifiers=[0x0F, 0x77], cpu=["MMX"])
3816
3817#
3818# movd
3819#
3820add_group("movd",
3821    cpu=["MMX"],
3822    opcode=[0x0F, 0x6E],
3823    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
3824              Operand(type="RM", size=32, relaxed=True, dest="EA")])
3825add_group("movd",
3826    cpu=["MMX"],
3827    opersize=64,
3828    opcode=[0x0F, 0x6E],
3829    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
3830              Operand(type="RM", size=64, relaxed=True, dest="EA")])
3831add_group("movd",
3832    cpu=["MMX"],
3833    opcode=[0x0F, 0x7E],
3834    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
3835              Operand(type="SIMDReg", size=64, dest="Spare")])
3836add_group("movd",
3837    cpu=["MMX"],
3838    opersize=64,
3839    opcode=[0x0F, 0x7E],
3840    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
3841              Operand(type="SIMDReg", size=64, dest="Spare")])
3842add_group("movd",
3843    cpu=["SSE2"],
3844    prefix=0x66,
3845    opcode=[0x0F, 0x6E],
3846    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3847              Operand(type="RM", size=32, relaxed=True, dest="EA")])
3848add_group("movd",
3849    cpu=["SSE2"],
3850    opersize=64,
3851    prefix=0x66,
3852    opcode=[0x0F, 0x6E],
3853    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3854              Operand(type="RM", size=64, relaxed=True, dest="EA")])
3855add_group("movd",
3856    cpu=["SSE2"],
3857    prefix=0x66,
3858    opcode=[0x0F, 0x7E],
3859    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
3860              Operand(type="SIMDReg", size=128, dest="Spare")])
3861add_group("movd",
3862    cpu=["SSE2"],
3863    opersize=64,
3864    prefix=0x66,
3865    opcode=[0x0F, 0x7E],
3866    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
3867              Operand(type="SIMDReg", size=128, dest="Spare")])
3868
3869add_insn("movd", "movd")
3870
3871#
3872# movq
3873#
3874
3875# MMX forms
3876add_group("movq",
3877    cpu=["MMX"],
3878    parsers=["nasm"],
3879    opcode=[0x0F, 0x6F],
3880    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
3881              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
3882add_group("movq",
3883    cpu=["MMX"],
3884    parsers=["nasm"],
3885    opersize=64,
3886    opcode=[0x0F, 0x6E],
3887    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
3888              Operand(type="RM", size=64, relaxed=True, dest="EA")])
3889add_group("movq",
3890    cpu=["MMX"],
3891    parsers=["nasm"],
3892    opcode=[0x0F, 0x7F],
3893    operands=[Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
3894              Operand(type="SIMDReg", size=64, dest="Spare")])
3895add_group("movq",
3896    cpu=["MMX"],
3897    parsers=["nasm"],
3898    opersize=64,
3899    opcode=[0x0F, 0x7E],
3900    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
3901              Operand(type="SIMDReg", size=64, dest="Spare")])
3902
3903# SSE2 forms
3904add_group("movq",
3905    cpu=["SSE2"],
3906    parsers=["nasm"],
3907    prefix=0xF3,
3908    opcode=[0x0F, 0x7E],
3909    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3910              Operand(type="SIMDReg", size=128, dest="EA")])
3911add_group("movq",
3912    cpu=["SSE2"],
3913    parsers=["nasm"],
3914    prefix=0xF3,
3915    opcode=[0x0F, 0x7E],
3916    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3917              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
3918add_group("movq",
3919    cpu=["SSE2"],
3920    parsers=["nasm"],
3921    opersize=64,
3922    prefix=0x66,
3923    opcode=[0x0F, 0x6E],
3924    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3925              Operand(type="RM", size=64, relaxed=True, dest="EA")])
3926add_group("movq",
3927    cpu=["SSE2"],
3928    parsers=["nasm"],
3929    prefix=0x66,
3930    opcode=[0x0F, 0xD6],
3931    operands=[Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
3932              Operand(type="SIMDReg", size=128, dest="Spare")])
3933add_group("movq",
3934    cpu=["SSE2"],
3935    parsers=["nasm"],
3936    opersize=64,
3937    prefix=0x66,
3938    opcode=[0x0F, 0x7E],
3939    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
3940              Operand(type="SIMDReg", size=128, dest="Spare")])
3941
3942add_insn("movq", "movq")
3943
3944add_group("mmxsse2",
3945    cpu=["MMX"],
3946    modifiers=["Op1Add"],
3947    opcode=[0x0F, 0x00],
3948    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
3949              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
3950add_group("mmxsse2",
3951    cpu=["SSE2"],
3952    modifiers=["Op1Add"],
3953    prefix=0x66,
3954    opcode=[0x0F, 0x00],
3955    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
3956              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
3957
3958add_insn("packssdw",  "mmxsse2", modifiers=[0x6B])
3959add_insn("packsswb",  "mmxsse2", modifiers=[0x63])
3960add_insn("packuswb",  "mmxsse2", modifiers=[0x67])
3961add_insn("paddb",     "mmxsse2", modifiers=[0xFC])
3962add_insn("paddw",     "mmxsse2", modifiers=[0xFD])
3963add_insn("paddd",     "mmxsse2", modifiers=[0xFE])
3964add_insn("paddq",     "mmxsse2", modifiers=[0xD4])
3965add_insn("paddsb",    "mmxsse2", modifiers=[0xEC])
3966add_insn("paddsw",    "mmxsse2", modifiers=[0xED])
3967add_insn("paddusb",   "mmxsse2", modifiers=[0xDC])
3968add_insn("paddusw",   "mmxsse2", modifiers=[0xDD])
3969add_insn("pand",      "mmxsse2", modifiers=[0xDB])
3970add_insn("pandn",     "mmxsse2", modifiers=[0xDF])
3971add_insn("pcmpeqb",   "mmxsse2", modifiers=[0x74])
3972add_insn("pcmpeqw",   "mmxsse2", modifiers=[0x75])
3973add_insn("pcmpeqd",   "mmxsse2", modifiers=[0x76])
3974add_insn("pcmpgtb",   "mmxsse2", modifiers=[0x64])
3975add_insn("pcmpgtw",   "mmxsse2", modifiers=[0x65])
3976add_insn("pcmpgtd",   "mmxsse2", modifiers=[0x66])
3977add_insn("pmaddwd",   "mmxsse2", modifiers=[0xF5])
3978add_insn("pmulhw",    "mmxsse2", modifiers=[0xE5])
3979add_insn("pmullw",    "mmxsse2", modifiers=[0xD5])
3980add_insn("por",       "mmxsse2", modifiers=[0xEB])
3981add_insn("psubb",     "mmxsse2", modifiers=[0xF8])
3982add_insn("psubw",     "mmxsse2", modifiers=[0xF9])
3983add_insn("psubd",     "mmxsse2", modifiers=[0xFA])
3984add_insn("psubq",     "mmxsse2", modifiers=[0xFB])
3985add_insn("psubsb",    "mmxsse2", modifiers=[0xE8])
3986add_insn("psubsw",    "mmxsse2", modifiers=[0xE9])
3987add_insn("psubusb",   "mmxsse2", modifiers=[0xD8])
3988add_insn("psubusw",   "mmxsse2", modifiers=[0xD9])
3989add_insn("punpckhbw", "mmxsse2", modifiers=[0x68])
3990add_insn("punpckhwd", "mmxsse2", modifiers=[0x69])
3991add_insn("punpckhdq", "mmxsse2", modifiers=[0x6A])
3992add_insn("punpcklbw", "mmxsse2", modifiers=[0x60])
3993add_insn("punpcklwd", "mmxsse2", modifiers=[0x61])
3994add_insn("punpckldq", "mmxsse2", modifiers=[0x62])
3995add_insn("pxor",      "mmxsse2", modifiers=[0xEF])
3996
3997# AVX versions don't support the MMX registers
3998add_insn("vpackssdw",  "xmm_xmm128_256avx2", modifiers=[0x66, 0x6B, VEXL0], avx=True)
3999add_insn("vpacksswb",  "xmm_xmm128_256avx2", modifiers=[0x66, 0x63, VEXL0], avx=True)
4000add_insn("vpackuswb",  "xmm_xmm128_256avx2", modifiers=[0x66, 0x67, VEXL0], avx=True)
4001add_insn("vpaddb",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xFC, VEXL0], avx=True)
4002add_insn("vpaddw",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xFD, VEXL0], avx=True)
4003add_insn("vpaddd",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xFE, VEXL0], avx=True)
4004add_insn("vpaddq",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xD4, VEXL0], avx=True)
4005add_insn("vpaddsb",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xEC, VEXL0], avx=True)
4006add_insn("vpaddsw",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xED, VEXL0], avx=True)
4007add_insn("vpaddusb",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xDC, VEXL0], avx=True)
4008add_insn("vpaddusw",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xDD, VEXL0], avx=True)
4009add_insn("vpand",      "xmm_xmm128_256avx2", modifiers=[0x66, 0xDB, VEXL0], avx=True)
4010add_insn("vpandn",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xDF, VEXL0], avx=True)
4011add_insn("vpcmpeqb",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x74, VEXL0], avx=True)
4012add_insn("vpcmpeqw",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x75, VEXL0], avx=True)
4013add_insn("vpcmpeqd",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x76, VEXL0], avx=True)
4014add_insn("vpcmpgtb",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x64, VEXL0], avx=True)
4015add_insn("vpcmpgtw",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x65, VEXL0], avx=True)
4016add_insn("vpcmpgtd",   "xmm_xmm128_256avx2", modifiers=[0x66, 0x66, VEXL0], avx=True)
4017add_insn("vpmaddwd",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xF5, VEXL0], avx=True)
4018add_insn("vpmulhw",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xE5, VEXL0], avx=True)
4019add_insn("vpmullw",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xD5, VEXL0], avx=True)
4020add_insn("vpor",       "xmm_xmm128_256avx2", modifiers=[0x66, 0xEB, VEXL0], avx=True)
4021add_insn("vpsubb",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xF8, VEXL0], avx=True)
4022add_insn("vpsubw",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xF9, VEXL0], avx=True)
4023add_insn("vpsubd",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xFA, VEXL0], avx=True)
4024add_insn("vpsubq",     "xmm_xmm128_256avx2", modifiers=[0x66, 0xFB, VEXL0], avx=True)
4025add_insn("vpsubsb",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xE8, VEXL0], avx=True)
4026add_insn("vpsubsw",    "xmm_xmm128_256avx2", modifiers=[0x66, 0xE9, VEXL0], avx=True)
4027add_insn("vpsubusb",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xD8, VEXL0], avx=True)
4028add_insn("vpsubusw",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xD9, VEXL0], avx=True)
4029add_insn("vpunpckhbw", "xmm_xmm128_256avx2", modifiers=[0x66, 0x68, VEXL0], avx=True)
4030add_insn("vpunpckhwd", "xmm_xmm128_256avx2", modifiers=[0x66, 0x69, VEXL0], avx=True)
4031add_insn("vpunpckhdq", "xmm_xmm128_256avx2", modifiers=[0x66, 0x6A, VEXL0], avx=True)
4032add_insn("vpunpcklbw", "xmm_xmm128_256avx2", modifiers=[0x66, 0x60, VEXL0], avx=True)
4033add_insn("vpunpcklwd", "xmm_xmm128_256avx2", modifiers=[0x66, 0x61, VEXL0], avx=True)
4034add_insn("vpunpckldq", "xmm_xmm128_256avx2", modifiers=[0x66, 0x62, VEXL0], avx=True)
4035add_insn("vpxor",      "xmm_xmm128_256avx2", modifiers=[0x66, 0xEF, VEXL0], avx=True)
4036
4037add_group("pshift",
4038    cpu=["MMX"],
4039    modifiers=["Op1Add"],
4040    opcode=[0x0F, 0x00],
4041    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4042              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
4043add_group("pshift",
4044    cpu=["MMX"],
4045    modifiers=["Gap", "Op1Add", "SpAdd"],
4046    opcode=[0x0F, 0x00],
4047    spare=0,
4048    operands=[Operand(type="SIMDReg", size=64, dest="EA"),
4049              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4050add_group("pshift",
4051    cpu=["SSE2"],
4052    modifiers=["Op1Add"],
4053    prefix=0x66,
4054    opcode=[0x0F, 0x00],
4055    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4056              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4057add_group("pshift",
4058    cpu=["SSE2"],
4059    modifiers=["Gap", "Op1Add", "SpAdd"],
4060    prefix=0x66,
4061    opcode=[0x0F, 0x00],
4062    spare=0,
4063    operands=[Operand(type="SIMDReg", size=128, dest="EA"),
4064              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4065
4066add_insn("psllw", "pshift", modifiers=[0xF1, 0x71, 6])
4067add_insn("pslld", "pshift", modifiers=[0xF2, 0x72, 6])
4068add_insn("psllq", "pshift", modifiers=[0xF3, 0x73, 6])
4069add_insn("psraw", "pshift", modifiers=[0xE1, 0x71, 4])
4070add_insn("psrad", "pshift", modifiers=[0xE2, 0x72, 4])
4071add_insn("psrlw", "pshift", modifiers=[0xD1, 0x71, 2])
4072add_insn("psrld", "pshift", modifiers=[0xD2, 0x72, 2])
4073add_insn("psrlq", "pshift", modifiers=[0xD3, 0x73, 2])
4074
4075# Ran out of modifiers, so AVX has to be separate
4076for cpu, sz in zip(["AVX", "AVX2"], [128, 256]):
4077    add_group("vpshift",
4078        cpu=[cpu],
4079        modifiers=["Op1Add"],
4080        vex=sz,
4081        prefix=0x66,
4082        opcode=[0x0F, 0x00],
4083        operands=[Operand(type="SIMDReg", size=sz, dest="SpareVEX"),
4084                  Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4085    add_group("vpshift",
4086        cpu=[cpu],
4087        modifiers=["Gap", "Op1Add", "SpAdd"],
4088        vex=sz,
4089        prefix=0x66,
4090        opcode=[0x0F, 0x00],
4091        spare=0,
4092        operands=[Operand(type="SIMDReg", size=sz, dest="EAVEX"),
4093                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4094    add_group("vpshift",
4095        cpu=[cpu],
4096        modifiers=["Op1Add"],
4097        vex=sz,
4098        prefix=0x66,
4099        opcode=[0x0F, 0x00],
4100        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
4101                  Operand(type="SIMDReg", size=sz, dest="VEX"),
4102                  Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4103    add_group("vpshift",
4104        cpu=[cpu],
4105        modifiers=["Gap", "Op1Add", "SpAdd"],
4106        vex=sz,
4107        prefix=0x66,
4108        opcode=[0x0F, 0x00],
4109        spare=0,
4110        operands=[Operand(type="SIMDReg", size=sz, dest="VEX"),
4111                  Operand(type="SIMDReg", size=sz, dest="EA"),
4112                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4113
4114add_insn("vpsllw", "vpshift", modifiers=[0xF1, 0x71, 6])
4115add_insn("vpslld", "vpshift", modifiers=[0xF2, 0x72, 6])
4116add_insn("vpsllq", "vpshift", modifiers=[0xF3, 0x73, 6])
4117add_insn("vpsraw", "vpshift", modifiers=[0xE1, 0x71, 4])
4118add_insn("vpsrad", "vpshift", modifiers=[0xE2, 0x72, 4])
4119add_insn("vpsrlw", "vpshift", modifiers=[0xD1, 0x71, 2])
4120add_insn("vpsrld", "vpshift", modifiers=[0xD2, 0x72, 2])
4121add_insn("vpsrlq", "vpshift", modifiers=[0xD3, 0x73, 2])
4122
4123#
4124# PIII (Katmai) new instructions / SIMD instructions
4125#
4126add_insn("pavgb",   "mmxsse2", modifiers=[0xE0], cpu=["P3", "MMX"])
4127add_insn("pavgw",   "mmxsse2", modifiers=[0xE3], cpu=["P3", "MMX"])
4128add_insn("pmaxsw",  "mmxsse2", modifiers=[0xEE], cpu=["P3", "MMX"])
4129add_insn("pmaxub",  "mmxsse2", modifiers=[0xDE], cpu=["P3", "MMX"])
4130add_insn("pminsw",  "mmxsse2", modifiers=[0xEA], cpu=["P3", "MMX"])
4131add_insn("pminub",  "mmxsse2", modifiers=[0xDA], cpu=["P3", "MMX"])
4132add_insn("pmulhuw", "mmxsse2", modifiers=[0xE4], cpu=["P3", "MMX"])
4133add_insn("psadbw",  "mmxsse2", modifiers=[0xF6], cpu=["P3", "MMX"])
4134
4135# AVX versions don't support MMX register
4136add_insn("vpavgb",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xE0, VEXL0], avx=True)
4137add_insn("vpavgw",   "xmm_xmm128_256avx2", modifiers=[0x66, 0xE3, VEXL0], avx=True)
4138add_insn("vpmaxsw",  "xmm_xmm128_256avx2", modifiers=[0x66, 0xEE, VEXL0], avx=True)
4139add_insn("vpmaxub",  "xmm_xmm128_256avx2", modifiers=[0x66, 0xDE, VEXL0], avx=True)
4140add_insn("vpminsw",  "xmm_xmm128_256avx2", modifiers=[0x66, 0xEA, VEXL0], avx=True)
4141add_insn("vpminub",  "xmm_xmm128_256avx2", modifiers=[0x66, 0xDA, VEXL0], avx=True)
4142add_insn("vpmulhuw", "xmm_xmm128_256avx2", modifiers=[0x66, 0xE4, VEXL0], avx=True)
4143add_insn("vpsadbw",  "xmm_xmm128_256avx2", modifiers=[0x66, 0xF6, VEXL0], avx=True)
4144
4145add_insn("prefetchnta", "twobytemem", modifiers=[0, 0x0F, 0x18], cpu=["P3"])
4146add_insn("prefetcht0", "twobytemem", modifiers=[1, 0x0F, 0x18], cpu=["P3"])
4147add_insn("prefetcht1", "twobytemem", modifiers=[2, 0x0F, 0x18], cpu=["P3"])
4148add_insn("prefetcht2", "twobytemem", modifiers=[3, 0x0F, 0x18], cpu=["P3"])
4149
4150add_insn("sfence", "threebyte", modifiers=[0x0F, 0xAE, 0xF8], cpu=["P3"])
4151
4152add_group("xmm_xmm128_256",
4153    cpu=["SSE"],
4154    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4155    prefix=0x00,
4156    opcode=[0x0F, 0x00],
4157    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4158              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4159add_group("xmm_xmm128_256",
4160    cpu=["AVX"],
4161    modifiers=["PreAdd", "Op1Add"],
4162    vex=128,
4163    prefix=0x00,
4164    opcode=[0x0F, 0x00],
4165    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4166              Operand(type="SIMDReg", size=128, dest="VEX"),
4167              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4168add_group("xmm_xmm128_256",
4169    cpu=["AVX"],
4170    modifiers=["PreAdd", "Op1Add"],
4171    vex=256,
4172    prefix=0x00,
4173    opcode=[0x0F, 0x00],
4174    operands=[Operand(type="SIMDReg", size=256, dest="SpareVEX"),
4175              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4176add_group("xmm_xmm128_256",
4177    cpu=["AVX"],
4178    modifiers=["PreAdd", "Op1Add"],
4179    vex=256,
4180    prefix=0x00,
4181    opcode=[0x0F, 0x00],
4182    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4183              Operand(type="SIMDReg", size=256, dest="VEX"),
4184              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4185
4186# Same as above, except 256-bit version only available in AVX2
4187add_group("xmm_xmm128_256avx2",
4188    cpu=["SSE"],
4189    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4190    prefix=0x00,
4191    opcode=[0x0F, 0x00],
4192    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4193              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4194add_group("xmm_xmm128_256avx2",
4195    cpu=["AVX"],
4196    modifiers=["PreAdd", "Op1Add"],
4197    vex=128,
4198    prefix=0x00,
4199    opcode=[0x0F, 0x00],
4200    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4201              Operand(type="SIMDReg", size=128, dest="VEX"),
4202              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4203add_group("xmm_xmm128_256avx2",
4204    cpu=["AVX2"],
4205    modifiers=["PreAdd", "Op1Add"],
4206    vex=256,
4207    prefix=0x00,
4208    opcode=[0x0F, 0x00],
4209    operands=[Operand(type="SIMDReg", size=256, dest="SpareVEX"),
4210              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4211add_group("xmm_xmm128_256avx2",
4212    cpu=["AVX2"],
4213    modifiers=["PreAdd", "Op1Add"],
4214    vex=256,
4215    prefix=0x00,
4216    opcode=[0x0F, 0x00],
4217    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4218              Operand(type="SIMDReg", size=256, dest="VEX"),
4219              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4220
4221# Version that does not allow YMM registers
4222add_group("xmm_xmm128",
4223    cpu=["SSE"],
4224    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4225    prefix=0x00,
4226    opcode=[0x0F, 0x00],
4227    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4228              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4229add_group("xmm_xmm128",
4230    cpu=["AVX"],
4231    modifiers=["PreAdd", "Op1Add"],
4232    vex=128,
4233    prefix=0x00,
4234    opcode=[0x0F, 0x00],
4235    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4236              Operand(type="SIMDReg", size=128, dest="VEX"),
4237              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4238
4239add_insn("addps",    "xmm_xmm128", modifiers=[0, 0x58])
4240add_insn("andnps",   "xmm_xmm128", modifiers=[0, 0x55])
4241add_insn("andps",    "xmm_xmm128", modifiers=[0, 0x54])
4242add_insn("divps",    "xmm_xmm128", modifiers=[0, 0x5E])
4243add_insn("maxps",    "xmm_xmm128", modifiers=[0, 0x5F])
4244add_insn("minps",    "xmm_xmm128", modifiers=[0, 0x5D])
4245add_insn("mulps",    "xmm_xmm128", modifiers=[0, 0x59])
4246add_insn("orps",     "xmm_xmm128", modifiers=[0, 0x56])
4247add_insn("rcpps",    "xmm_xmm128", modifiers=[0, 0x53])
4248add_insn("rsqrtps",  "xmm_xmm128", modifiers=[0, 0x52])
4249add_insn("sqrtps",   "xmm_xmm128", modifiers=[0, 0x51])
4250add_insn("subps",    "xmm_xmm128", modifiers=[0, 0x5C])
4251add_insn("unpckhps", "xmm_xmm128", modifiers=[0, 0x15])
4252add_insn("unpcklps", "xmm_xmm128", modifiers=[0, 0x14])
4253add_insn("xorps",    "xmm_xmm128", modifiers=[0, 0x57])
4254
4255add_insn("vaddps",    "xmm_xmm128_256", modifiers=[0, 0x58, VEXL0], avx=True)
4256add_insn("vandnps",   "xmm_xmm128_256", modifiers=[0, 0x55, VEXL0], avx=True)
4257add_insn("vandps",    "xmm_xmm128_256", modifiers=[0, 0x54, VEXL0], avx=True)
4258add_insn("vdivps",    "xmm_xmm128_256", modifiers=[0, 0x5E, VEXL0], avx=True)
4259add_insn("vmaxps",    "xmm_xmm128_256", modifiers=[0, 0x5F, VEXL0], avx=True)
4260add_insn("vminps",    "xmm_xmm128_256", modifiers=[0, 0x5D, VEXL0], avx=True)
4261add_insn("vmulps",    "xmm_xmm128_256", modifiers=[0, 0x59, VEXL0], avx=True)
4262add_insn("vorps",     "xmm_xmm128_256", modifiers=[0, 0x56, VEXL0], avx=True)
4263# vrcpps, vrsqrtps, and vsqrtps don't add third operand
4264add_insn("vsubps",    "xmm_xmm128_256", modifiers=[0, 0x5C, VEXL0], avx=True)
4265add_insn("vunpckhps", "xmm_xmm128_256", modifiers=[0, 0x15, VEXL0], avx=True)
4266add_insn("vunpcklps", "xmm_xmm128_256", modifiers=[0, 0x14, VEXL0], avx=True)
4267add_insn("vxorps",    "xmm_xmm128_256", modifiers=[0, 0x57, VEXL0], avx=True)
4268
4269add_group("cvt_rx_xmm32",
4270    suffix="l",
4271    cpu=["SSE"],
4272    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4273    prefix=0x00,
4274    opcode=[0x0F, 0x00],
4275    operands=[Operand(type="Reg", size=32, dest="Spare"),
4276              Operand(type="SIMDReg", size=128, dest="EA")])
4277add_group("cvt_rx_xmm32",
4278    suffix="l",
4279    cpu=["SSE"],
4280    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4281    prefix=0x00,
4282    opcode=[0x0F, 0x00],
4283    operands=[Operand(type="Reg", size=32, dest="Spare"),
4284              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4285# REX
4286add_group("cvt_rx_xmm32",
4287    suffix="q",
4288    cpu=["SSE"],
4289    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4290    opersize=64,
4291    prefix=0x00,
4292    opcode=[0x0F, 0x00],
4293    operands=[Operand(type="Reg", size=64, dest="Spare"),
4294              Operand(type="SIMDReg", size=128, dest="EA")])
4295add_group("cvt_rx_xmm32",
4296    suffix="q",
4297    cpu=["SSE"],
4298    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4299    opersize=64,
4300    prefix=0x00,
4301    opcode=[0x0F, 0x00],
4302    operands=[Operand(type="Reg", size=64, dest="Spare"),
4303              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4304
4305add_insn("cvtss2si", "cvt_rx_xmm32", modifiers=[0xF3, 0x2D])
4306add_insn("cvttss2si", "cvt_rx_xmm32", modifiers=[0xF3, 0x2C])
4307add_insn("vcvtss2si", "cvt_rx_xmm32", modifiers=[0xF3, 0x2D, VEXL0], avx=True)
4308add_insn("vcvttss2si", "cvt_rx_xmm32", modifiers=[0xF3, 0x2C, VEXL0], avx=True)
4309
4310add_group("cvt_mm_xmm64",
4311    cpu=["SSE"],
4312    modifiers=["Op1Add"],
4313    opcode=[0x0F, 0x00],
4314    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4315              Operand(type="SIMDReg", size=128, dest="EA")])
4316add_group("cvt_mm_xmm64",
4317    cpu=["SSE"],
4318    modifiers=["Op1Add"],
4319    opcode=[0x0F, 0x00],
4320    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4321              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
4322
4323add_insn("cvtps2pi", "cvt_mm_xmm64", modifiers=[0x2D])
4324add_insn("cvttps2pi", "cvt_mm_xmm64", modifiers=[0x2C])
4325
4326add_group("cvt_xmm_mm_ps",
4327    cpu=["SSE"],
4328    modifiers=["Op1Add"],
4329    opcode=[0x0F, 0x00],
4330    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4331              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
4332
4333add_insn("cvtpi2ps", "cvt_xmm_mm_ps", modifiers=[0x2A])
4334
4335# Memory size can be relaxed only in BITS=32 case, where there's no
4336# ambiguity.
4337add_group("cvt_xmm_rmx",
4338    suffix="l",
4339    cpu=["SSE"],
4340    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4341    prefix=0x00,
4342    opcode=[0x0F, 0x00],
4343    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4344              Operand(type="RM", size=32, dest="EA")])
4345add_group("cvt_xmm_rmx",
4346    suffix="l",
4347    cpu=["SSE"],
4348    not64=True,
4349    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4350    prefix=0x00,
4351    opcode=[0x0F, 0x00],
4352    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4353              Operand(type="RM", size=32, relaxed=True, dest="EA")])
4354# REX
4355add_group("cvt_xmm_rmx",
4356    suffix="q",
4357    cpu=["SSE"],
4358    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4359    opersize=64,
4360    prefix=0x00,
4361    opcode=[0x0F, 0x00],
4362    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4363              Operand(type="RM", size=64, dest="EA")])
4364add_group("cvt_xmm_rmx",
4365    suffix="l",
4366    cpu=["AVX"],
4367    not64=True,
4368    modifiers=["PreAdd", "Op1Add"],
4369    vex=128,
4370    prefix=0x00,
4371    opcode=[0x0F, 0x00],
4372    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4373              Operand(type="SIMDReg", size=128, dest="VEX"),
4374              Operand(type="RM", size=32, relaxed=True, dest="EA")])
4375add_group("cvt_xmm_rmx",
4376    suffix="l",
4377    cpu=["AVX"],
4378    modifiers=["PreAdd", "Op1Add"],
4379    vex=128,
4380    prefix=0x00,
4381    opcode=[0x0F, 0x00],
4382    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4383              Operand(type="SIMDReg", size=128, dest="VEX"),
4384              Operand(type="RM", size=32, dest="EA")])
4385add_group("cvt_xmm_rmx",
4386    suffix="q",
4387    cpu=["AVX"],
4388    modifiers=["PreAdd", "Op1Add"],
4389    vex=128,
4390    opersize=64,
4391    prefix=0x00,
4392    opcode=[0x0F, 0x00],
4393    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4394              Operand(type="SIMDReg", size=128, dest="VEX"),
4395              Operand(type="RM", size=64, dest="EA")])
4396
4397add_insn("cvtsi2ss", "cvt_xmm_rmx", modifiers=[0xF3, 0x2A])
4398add_insn("vcvtsi2ss", "cvt_xmm_rmx", modifiers=[0xF3, 0x2A, VEXL0], avx=True)
4399
4400add_group("xmm_xmm32",
4401    cpu=["SSE"],
4402    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4403    prefix=0x00,
4404    opcode=[0x0F, 0x00],
4405    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4406              Operand(type="SIMDReg", size=128, dest="EA")])
4407add_group("xmm_xmm32",
4408    cpu=["SSE"],
4409    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4410    prefix=0x00,
4411    opcode=[0x0F, 0x00],
4412    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4413              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4414add_group("xmm_xmm32",
4415    cpu=["AVX"],
4416    modifiers=["PreAdd", "Op1Add"],
4417    vex=128,
4418    prefix=0x00,
4419    opcode=[0x0F, 0x00],
4420    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4421              Operand(type="SIMDReg", size=128, dest="VEX"),
4422              Operand(type="SIMDReg", size=128, dest="EA")])
4423add_group("xmm_xmm32",
4424    cpu=["AVX"],
4425    modifiers=["PreAdd", "Op1Add"],
4426    vex=128,
4427    prefix=0x00,
4428    opcode=[0x0F, 0x00],
4429    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4430              Operand(type="SIMDReg", size=128, dest="VEX"),
4431              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4432
4433add_insn("addss",   "xmm_xmm32", modifiers=[0xF3, 0x58])
4434add_insn("comiss",  "xmm_xmm32", modifiers=[0, 0x2F])
4435add_insn("divss",   "xmm_xmm32", modifiers=[0xF3, 0x5E])
4436add_insn("maxss",   "xmm_xmm32", modifiers=[0xF3, 0x5F])
4437add_insn("minss",   "xmm_xmm32", modifiers=[0xF3, 0x5D])
4438add_insn("mulss",   "xmm_xmm32", modifiers=[0xF3, 0x59])
4439add_insn("rcpss",   "xmm_xmm32", modifiers=[0xF3, 0x53])
4440add_insn("rsqrtss", "xmm_xmm32", modifiers=[0xF3, 0x52])
4441add_insn("sqrtss",  "xmm_xmm32", modifiers=[0xF3, 0x51])
4442add_insn("subss",   "xmm_xmm32", modifiers=[0xF3, 0x5C])
4443add_insn("ucomiss", "xmm_xmm32", modifiers=[0, 0x2E])
4444
4445add_insn("vaddss",   "xmm_xmm32", modifiers=[0xF3, 0x58, VEXL0], avx=True)
4446# vcomiss and vucomiss are only two operand
4447add_insn("vdivss",   "xmm_xmm32", modifiers=[0xF3, 0x5E, VEXL0], avx=True)
4448add_insn("vmaxss",   "xmm_xmm32", modifiers=[0xF3, 0x5F, VEXL0], avx=True)
4449add_insn("vminss",   "xmm_xmm32", modifiers=[0xF3, 0x5D, VEXL0], avx=True)
4450add_insn("vmulss",   "xmm_xmm32", modifiers=[0xF3, 0x59, VEXL0], avx=True)
4451add_insn("vrcpss",   "xmm_xmm32", modifiers=[0xF3, 0x53, VEXL0], avx=True)
4452add_insn("vrsqrtss", "xmm_xmm32", modifiers=[0xF3, 0x52, VEXL0], avx=True)
4453add_insn("vsqrtss",  "xmm_xmm32", modifiers=[0xF3, 0x51, VEXL0], avx=True)
4454add_insn("vsubss",   "xmm_xmm32", modifiers=[0xF3, 0x5C, VEXL0], avx=True)
4455
4456add_group("ssecmp_128",
4457    cpu=["SSE"],
4458    modifiers=["Imm8", "PreAdd", "SetVEX"],
4459    opcode=[0x0F, 0xC2],
4460    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4461              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4462add_group("ssecmp_128",
4463    cpu=["AVX"],
4464    modifiers=["Imm8", "PreAdd"],
4465    vex=128,
4466    opcode=[0x0F, 0xC2],
4467    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4468              Operand(type="SIMDReg", size=128, dest="VEX"),
4469              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4470add_group("ssecmp_128",
4471    cpu=["AVX"],
4472    modifiers=["Imm8", "PreAdd"],
4473    vex=256,
4474    opcode=[0x0F, 0xC2],
4475    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4476              Operand(type="SIMDReg", size=256, dest="VEX"),
4477              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4478
4479add_group("ssecmp_32",
4480    cpu=["SSE"],
4481    modifiers=["Imm8", "PreAdd", "SetVEX"],
4482    prefix=0x00,
4483    opcode=[0x0F, 0xC2],
4484    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4485              Operand(type="SIMDReg", size=128, dest="EA")])
4486add_group("ssecmp_32",
4487    cpu=["SSE"],
4488    modifiers=["Imm8", "PreAdd", "SetVEX"],
4489    prefix=0x00,
4490    opcode=[0x0F, 0xC2],
4491    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4492              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4493add_group("ssecmp_32",
4494    cpu=["AVX"],
4495    modifiers=["Imm8", "PreAdd"],
4496    vex=128,
4497    prefix=0x00,
4498    opcode=[0x0F, 0xC2],
4499    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4500              Operand(type="SIMDReg", size=128, dest="VEX"),
4501              Operand(type="SIMDReg", size=128, dest="EA")])
4502add_group("ssecmp_32",
4503    cpu=["AVX"],
4504    modifiers=["Imm8", "PreAdd"],
4505    vex=128,
4506    prefix=0x00,
4507    opcode=[0x0F, 0xC2],
4508    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4509              Operand(type="SIMDReg", size=128, dest="VEX"),
4510              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4511
4512ssecoms = [(0x0, "eq"),
4513           (0x1, "lt"),
4514           (0x2, "le"),
4515           (0x3, "unord"),
4516           (0x4, "neq"),
4517           (0x5, "nlt"),
4518           (0x6, "nle"),
4519           (0x7, "ord")]
4520for ib, cc in ssecoms:
4521    add_insn("cmp"+cc+"ps", "ssecmp_128", modifiers=[ib])
4522    add_insn("cmp"+cc+"ss", "ssecmp_32", modifiers=[ib, 0xF3])
4523
4524avxcoms = [(0x00, "eq"),
4525           (0x01, "lt"),
4526           (0x02, "le"),
4527           (0x03, "unord"),
4528           (0x04, "neq"),
4529           (0x05, "nlt"),
4530           (0x06, "nle"),
4531           (0x07, "ord"),
4532           (0x08, "eq_uq"),
4533           (0x09, "nge"),
4534           (0x0a, "ngt"),
4535           (0x0b, "false"),
4536           (0x0c, "neq_oq"),
4537           (0x0d, "ge"),
4538           (0x0e, "gt"),
4539           (0x0f, "true"),
4540           (0x10, "eq_os"),
4541           (0x11, "lt_oq"),
4542           (0x12, "le_oq"),
4543           (0x13, "unord_s"),
4544           (0x14, "neq_us"),
4545           (0x15, "nlt_uq"),
4546           (0x16, "nle_uq"),
4547           (0x17, "ord_s"),
4548           (0x18, "eq_us"),
4549           (0x19, "nge_uq"),
4550           (0x1a, "ngt_uq"),
4551           (0x1b, "false_os"),
4552           (0x1c, "neq_os"),
4553           (0x1d, "ge_oq"),
4554           (0x1e, "gt_oq"),
4555           (0x1f, "true_us")]
4556for ib, cc in avxcoms:
4557    add_insn("vcmp"+cc+"ps", "ssecmp_128", modifiers=[ib, 0, VEXL0], avx=True)
4558    add_insn("vcmp"+cc+"ss", "ssecmp_32", modifiers=[ib, 0xF3, VEXL0], avx=True)
4559
4560add_group("xmm_xmm128_imm",
4561    cpu=["SSE"],
4562    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4563    opcode=[0x0F, 0x00],
4564    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4565              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4566              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4567
4568add_insn("cmpps", "xmm_xmm128_imm", modifiers=[0, 0xC2])
4569add_insn("shufps", "xmm_xmm128_imm", modifiers=[0, 0xC6])
4570
4571# YMM register AVX2 version of above
4572add_group("xmm_xmm128_imm_256avx2",
4573    cpu=["SSE"],
4574    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4575    opcode=[0x0F, 0x00],
4576    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4577              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4578              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4579add_group("xmm_xmm128_imm_256avx2",
4580    cpu=["AVX2"],
4581    modifiers=["PreAdd", "Op1Add"],
4582    vex=256,
4583    opcode=[0x0F, 0x00],
4584    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4585              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
4586              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4587
4588# YMM register and 4-operand version of above
4589add_group("xmm_xmm128_imm_256",
4590    cpu=["SSE"],
4591    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4592    opcode=[0x0F, 0x00],
4593    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4594              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4595              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4596add_group("xmm_xmm128_imm_256",
4597    cpu=["AVX"],
4598    modifiers=["PreAdd", "Op1Add"],
4599    vex=128,
4600    opcode=[0x0F, 0x00],
4601    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4602              Operand(type="SIMDReg", size=128, dest="VEX"),
4603              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4604              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4605add_group("xmm_xmm128_imm_256",
4606    cpu=["AVX"],
4607    modifiers=["PreAdd", "Op1Add"],
4608    vex=256,
4609    opcode=[0x0F, 0x00],
4610    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4611              Operand(type="SIMDReg", size=256, dest="VEX"),
4612              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
4613              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4614
4615add_insn("vcmpps", "xmm_xmm128_imm_256", modifiers=[0, 0xC2, VEXL0], avx=True)
4616add_insn("vshufps", "xmm_xmm128_imm_256", modifiers=[0, 0xC6, VEXL0], avx=True)
4617
4618add_group("xmm_xmm32_imm",
4619    cpu=["SSE"],
4620    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4621    prefix=0x00,
4622    opcode=[0x0F, 0x00],
4623    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4624              Operand(type="SIMDReg", size=128, dest="EA"),
4625              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4626add_group("xmm_xmm32_imm",
4627    cpu=["SSE"],
4628    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4629    prefix=0x00,
4630    opcode=[0x0F, 0x00],
4631    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4632              Operand(type="Mem", size=32, relaxed=True, dest="EA"),
4633              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4634add_group("xmm_xmm32_imm",
4635    cpu=["AVX"],
4636    modifiers=["PreAdd", "Op1Add"],
4637    vex=128,
4638    prefix=0x00,
4639    opcode=[0x0F, 0x00],
4640    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4641              Operand(type="SIMDReg", size=128, dest="VEX"),
4642              Operand(type="SIMDReg", size=128, dest="EA"),
4643              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4644add_group("xmm_xmm32_imm",
4645    cpu=["AVX"],
4646    modifiers=["PreAdd", "Op1Add"],
4647    vex=128,
4648    prefix=0x00,
4649    opcode=[0x0F, 0x00],
4650    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4651              Operand(type="SIMDReg", size=128, dest="VEX"),
4652              Operand(type="Mem", size=32, relaxed=True, dest="EA"),
4653              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4654
4655add_insn("cmpss", "xmm_xmm32_imm", modifiers=[0xF3, 0xC2])
4656add_insn("vcmpss", "xmm_xmm32_imm", modifiers=[0xF3, 0xC2, VEXL0], avx=True)
4657
4658add_group("ldstmxcsr",
4659    cpu=["SSE"],
4660    modifiers=["SpAdd", "SetVEX"],
4661    opcode=[0x0F, 0xAE],
4662    spare=0,
4663    operands=[Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4664
4665add_insn("ldmxcsr", "ldstmxcsr", modifiers=[2])
4666add_insn("stmxcsr", "ldstmxcsr", modifiers=[3])
4667add_insn("vldmxcsr", "ldstmxcsr", modifiers=[2, VEXL0], avx=True)
4668add_insn("vstmxcsr", "ldstmxcsr", modifiers=[3, VEXL0], avx=True)
4669
4670add_group("maskmovq",
4671    cpu=["MMX", "P3"],
4672    opcode=[0x0F, 0xF7],
4673    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4674              Operand(type="SIMDReg", size=64, dest="EA")])
4675
4676add_insn("maskmovq", "maskmovq")
4677
4678# Too many modifiers, so can't reuse first two cases for AVX version
4679# Just repeat and disable first two with noavx.
4680add_group("movau",
4681    cpu=["SSE"],
4682    modifiers=["PreAdd", "Op1Add"],
4683    notavx=True,
4684    prefix=0x00,
4685    opcode=[0x0F, 0x00],
4686    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4687              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4688add_group("movau",
4689    cpu=["SSE"],
4690    notavx=True,
4691    modifiers=["PreAdd", "Op1Add", "Op1Add"],
4692    prefix=0x00,
4693    opcode=[0x0F, 0x00],
4694    operands=[Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4695              Operand(type="SIMDReg", size=128, dest="Spare")])
4696add_group("movau",
4697    cpu=["AVX"],
4698    modifiers=["PreAdd", "Op1Add"],
4699    vex=128,
4700    opcode=[0x0F, 0x00],
4701    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4702              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
4703add_group("movau",
4704    cpu=["AVX"],
4705    modifiers=["PreAdd", "Op1Add", "Op1Add"],
4706    vex=128,
4707    opcode=[0x0F, 0x00],
4708    operands=[Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
4709              Operand(type="SIMDReg", size=128, dest="Spare")])
4710add_group("movau",
4711    cpu=["AVX"],
4712    modifiers=["PreAdd", "Op1Add"],
4713    vex=256,
4714    opcode=[0x0F, 0x00],
4715    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
4716              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
4717add_group("movau",
4718    cpu=["AVX"],
4719    modifiers=["PreAdd", "Op1Add", "Op1Add"],
4720    vex=256,
4721    opcode=[0x0F, 0x00],
4722    operands=[Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
4723              Operand(type="SIMDReg", size=256, dest="Spare")])
4724
4725add_insn("movaps", "movau", modifiers=[0, 0x28, 0x01])
4726add_insn("movups", "movau", modifiers=[0, 0x10, 0x01])
4727add_insn("vmovaps", "movau", modifiers=[0, 0x28, 0x01], avx=True)
4728add_insn("vmovups", "movau", modifiers=[0, 0x10, 0x01], avx=True)
4729
4730add_group("movhllhps",
4731    cpu=["SSE"],
4732    modifiers=["Op1Add", "SetVEX"],
4733    opcode=[0x0F, 0x00],
4734    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4735              Operand(type="SIMDReg", size=128, dest="EA")])
4736add_group("movhllhps",
4737    cpu=["AVX"],
4738    modifiers=["Op1Add"],
4739    vex=128,
4740    opcode=[0x0F, 0x00],
4741    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4742              Operand(type="SIMDReg", size=128, dest="VEX"),
4743              Operand(type="SIMDReg", size=128, dest="EA")])
4744
4745add_insn("movhlps", "movhllhps", modifiers=[0x12])
4746add_insn("movlhps", "movhllhps", modifiers=[0x16])
4747add_insn("vmovhlps", "movhllhps", modifiers=[0x12, VEXL0], avx=True)
4748add_insn("vmovlhps", "movhllhps", modifiers=[0x16, VEXL0], avx=True)
4749
4750add_group("movhlp",
4751    cpu=["SSE"],
4752    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4753    prefix=0x00,
4754    opcode=[0x0F, 0x00],
4755    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4756              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
4757add_group("movhlp",
4758    cpu=["SSE"],
4759    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4760    prefix=0x00,
4761    opcode=[0x0F, 0x01],
4762    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
4763              Operand(type="SIMDReg", size=128, dest="Spare")])
4764add_group("movhlp",
4765    cpu=["AVX"],
4766    modifiers=["PreAdd", "Op1Add"],
4767    vex=128,
4768    prefix=0x00,
4769    opcode=[0x0F, 0x00],
4770    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4771              Operand(type="SIMDReg", size=128, dest="VEX"),
4772              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
4773
4774add_insn("movhps", "movhlp", modifiers=[0, 0x16])
4775add_insn("movlps", "movhlp", modifiers=[0, 0x12])
4776add_insn("vmovhps", "movhlp", modifiers=[0, 0x16, VEXL0], avx=True)
4777add_insn("vmovlps", "movhlp", modifiers=[0, 0x12, VEXL0], avx=True)
4778
4779add_group("movmsk",
4780    suffix="l",
4781    cpu=["SSE"],
4782    modifiers=["PreAdd", "SetVEX"],
4783    prefix=0x00,
4784    opcode=[0x0F, 0x50],
4785    operands=[Operand(type="Reg", size=32, dest="Spare"),
4786              Operand(type="SIMDReg", size=128, dest="EA")])
4787add_group("movmsk",
4788    suffix="q",
4789    cpu=["SSE"],
4790    modifiers=["PreAdd", "SetVEX"],
4791    prefix=0x00,
4792    opersize=64,
4793    opcode=[0x0F, 0x50],
4794    operands=[Operand(type="Reg", size=64, dest="Spare"),
4795              Operand(type="SIMDReg", size=128, dest="EA")])
4796add_group("movmsk",
4797    suffix="l",
4798    cpu=["AVX"],
4799    modifiers=["PreAdd"],
4800    vex=256,
4801    prefix=0x00,
4802    opcode=[0x0F, 0x50],
4803    operands=[Operand(type="Reg", size=32, dest="Spare"),
4804              Operand(type="SIMDReg", size=256, dest="EA")])
4805add_group("movmsk",
4806    suffix="q",
4807    cpu=["SSE"],
4808    modifiers=["PreAdd"],
4809    vex=256,
4810    prefix=0x00,
4811    opersize=64,
4812    opcode=[0x0F, 0x50],
4813    operands=[Operand(type="Reg", size=64, dest="Spare"),
4814              Operand(type="SIMDReg", size=256, dest="EA")])
4815
4816add_insn("movmskps", "movmsk")
4817add_insn("vmovmskps", "movmsk", modifiers=[0, VEXL0], avx=True)
4818
4819add_group("movnt",
4820    cpu=["SSE"],
4821    modifiers=["PreAdd", "Op1Add", "SetVEX"],
4822    prefix=0x00,
4823    opcode=[0x0F, 0x00],
4824    operands=[Operand(type="Mem", size=128, relaxed=True, dest="EA"),
4825              Operand(type="SIMDReg", size=128, dest="Spare")])
4826add_group("movnt",
4827    cpu=["AVX"],
4828    modifiers=["PreAdd", "Op1Add"],
4829    vex=256,
4830    prefix=0x00,
4831    opcode=[0x0F, 0x00],
4832    operands=[Operand(type="Mem", size=256, relaxed=True, dest="EA"),
4833              Operand(type="SIMDReg", size=256, dest="Spare")])
4834
4835add_insn("movntps", "movnt", modifiers=[0, 0x2B])
4836add_insn("vmovntps", "movnt", modifiers=[0, 0x2B, VEXL0], avx=True)
4837
4838add_group("movntq",
4839    cpu=["SSE"],
4840    opcode=[0x0F, 0xE7],
4841    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
4842              Operand(type="SIMDReg", size=64, dest="Spare")])
4843
4844add_insn("movntq", "movntq")
4845
4846add_group("movss",
4847    cpu=["SSE"],
4848    modifiers=["SetVEX"],
4849    prefix=0xF3,
4850    opcode=[0x0F, 0x10],
4851    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4852              Operand(type="SIMDReg", size=128, dest="EA")])
4853add_group("movss",
4854    cpu=["SSE"],
4855    modifiers=["SetVEX"],
4856    prefix=0xF3,
4857    opcode=[0x0F, 0x10],
4858    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4859              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
4860add_group("movss",
4861    cpu=["SSE"],
4862    modifiers=["SetVEX"],
4863    prefix=0xF3,
4864    opcode=[0x0F, 0x11],
4865    operands=[Operand(type="Mem", size=32, relaxed=True, dest="EA"),
4866              Operand(type="SIMDReg", size=128, dest="Spare")])
4867add_group("movss",
4868    cpu=["AVX"],
4869    vex=128,
4870    prefix=0xF3,
4871    opcode=[0x0F, 0x10],
4872    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
4873              Operand(type="SIMDReg", size=128, dest="VEX"),
4874              Operand(type="SIMDReg", size=128, dest="EA")])
4875
4876add_insn("movss", "movss")
4877add_insn("vmovss", "movss", modifiers=[VEXL0], avx=True)
4878
4879add_group("pextrw",
4880    suffix="l",
4881    cpu=["MMX", "P3"],
4882    notavx=True,
4883    opcode=[0x0F, 0xC5],
4884    operands=[Operand(type="Reg", size=32, dest="Spare"),
4885              Operand(type="SIMDReg", size=64, dest="EA"),
4886              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4887add_group("pextrw",
4888    suffix="l",
4889    cpu=["SSE2"],
4890    modifiers=["SetVEX"],
4891    prefix=0x66,
4892    opcode=[0x0F, 0xC5],
4893    operands=[Operand(type="Reg", size=32, dest="Spare"),
4894              Operand(type="SIMDReg", size=128, dest="EA"),
4895              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4896add_group("pextrw",
4897    suffix="q",
4898    cpu=["MMX", "P3"],
4899    notavx=True,
4900    opersize=64,
4901    opcode=[0x0F, 0xC5],
4902    operands=[Operand(type="Reg", size=64, dest="Spare"),
4903              Operand(type="SIMDReg", size=64, dest="EA"),
4904              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4905add_group("pextrw",
4906    suffix="q",
4907    cpu=["SSE2"],
4908    modifiers=["SetVEX"],
4909    opersize=64,
4910    prefix=0x66,
4911    opcode=[0x0F, 0xC5],
4912    operands=[Operand(type="Reg", size=64, dest="Spare"),
4913              Operand(type="SIMDReg", size=128, dest="EA"),
4914              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4915# SSE41 instructions
4916add_group("pextrw",
4917    cpu=["SSE41"],
4918    modifiers=["SetVEX"],
4919    prefix=0x66,
4920    opcode=[0x0F, 0x3A, 0x15],
4921    operands=[Operand(type="Mem", size=16, relaxed=True, dest="EA"),
4922              Operand(type="SIMDReg", size=128, dest="Spare"),
4923              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4924add_group("pextrw",
4925    cpu=["SSE41"],
4926    modifiers=["SetVEX"],
4927    opersize=32,
4928    prefix=0x66,
4929    opcode=[0x0F, 0x3A, 0x15],
4930    operands=[Operand(type="Reg", size=32, dest="EA"),
4931              Operand(type="SIMDReg", size=128, dest="Spare"),
4932              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4933add_group("pextrw",
4934    cpu=["SSE41"],
4935    modifiers=["SetVEX"],
4936    opersize=64,
4937    prefix=0x66,
4938    opcode=[0x0F, 0x3A, 0x15],
4939    operands=[Operand(type="Reg", size=64, dest="EA"),
4940              Operand(type="SIMDReg", size=128, dest="Spare"),
4941              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4942
4943add_insn("pextrw", "pextrw")
4944add_insn("vpextrw", "pextrw", modifiers=[VEXL0], avx=True)
4945
4946add_group("pinsrw",
4947    suffix="l",
4948    cpu=["MMX", "P3"],
4949    notavx=True,
4950    opcode=[0x0F, 0xC4],
4951    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4952              Operand(type="Reg", size=32, dest="EA"),
4953              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4954add_group("pinsrw",
4955    suffix="q",
4956    cpu=["MMX", "P3"],
4957    notavx=True,
4958    def_opersize_64=64,
4959    opersize=64,
4960    opcode=[0x0F, 0xC4],
4961    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4962              Operand(type="Reg", size=64, dest="EA"),
4963              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4964add_group("pinsrw",
4965    suffix="l",
4966    cpu=["MMX", "P3"],
4967    notavx=True,
4968    opcode=[0x0F, 0xC4],
4969    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
4970              Operand(type="Mem", size=16, relaxed=True, dest="EA"),
4971              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4972add_group("pinsrw",
4973    suffix="l",
4974    cpu=["SSE2"],
4975    modifiers=["SetVEX"],
4976    prefix=0x66,
4977    opcode=[0x0F, 0xC4],
4978    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4979              Operand(type="Reg", size=32, dest="EA"),
4980              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4981add_group("pinsrw",
4982    suffix="q",
4983    cpu=["SSE2"],
4984    modifiers=["SetVEX"],
4985    def_opersize_64=64,
4986    opersize=64,
4987    prefix=0x66,
4988    opcode=[0x0F, 0xC4],
4989    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4990              Operand(type="Reg", size=64, dest="EA"),
4991              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
4992add_group("pinsrw",
4993    suffix="l",
4994    cpu=["SSE2"],
4995    modifiers=["SetVEX"],
4996    prefix=0x66,
4997    opcode=[0x0F, 0xC4],
4998    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
4999              Operand(type="Mem", size=16, relaxed=True, dest="EA"),
5000              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5001add_group("pinsrw",
5002    suffix="l",
5003    cpu=["AVX"],
5004    vex=128,
5005    prefix=0x66,
5006    opcode=[0x0F, 0xC4],
5007    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5008              Operand(type="SIMDReg", size=128, dest="VEX"),
5009              Operand(type="Reg", size=32, dest="EA"),
5010              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5011add_group("pinsrw",
5012    suffix="q",
5013    cpu=["AVX"],
5014    vex=128,
5015    def_opersize_64=64,
5016    opersize=64,
5017    prefix=0x66,
5018    opcode=[0x0F, 0xC4],
5019    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5020              Operand(type="SIMDReg", size=128, dest="VEX"),
5021              Operand(type="Reg", size=64, dest="EA"),
5022              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5023add_group("pinsrw",
5024    suffix="l",
5025    cpu=["AVX"],
5026    vex=128,
5027    prefix=0x66,
5028    opcode=[0x0F, 0xC4],
5029    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5030              Operand(type="SIMDReg", size=128, dest="VEX"),
5031              Operand(type="Mem", size=16, relaxed=True, dest="EA"),
5032              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5033
5034add_insn("pinsrw", "pinsrw")
5035add_insn("vpinsrw", "pinsrw", modifiers=[VEXL0], avx=True)
5036
5037add_group("pmovmskb",
5038    suffix="l",
5039    cpu=["MMX", "P3"],
5040    notavx=True,
5041    opcode=[0x0F, 0xD7],
5042    operands=[Operand(type="Reg", size=32, dest="Spare"),
5043              Operand(type="SIMDReg", size=64, dest="EA")])
5044add_group("pmovmskb",
5045    suffix="l",
5046    cpu=["SSE2"],
5047    modifiers=["SetVEX"],
5048    prefix=0x66,
5049    opcode=[0x0F, 0xD7],
5050    operands=[Operand(type="Reg", size=32, dest="Spare"),
5051              Operand(type="SIMDReg", size=128, dest="EA")])
5052add_group("pmovmskb",
5053    suffix="l",
5054    cpu=["AVX2"],
5055    vex=256,
5056    prefix=0x66,
5057    opcode=[0x0F, 0xD7],
5058    operands=[Operand(type="Reg", size=32, dest="Spare"),
5059              Operand(type="SIMDReg", size=256, dest="EA")])
5060add_group("pmovmskb",
5061    suffix="q",
5062    cpu=["MMX", "P3"],
5063    notavx=True,
5064    opersize=64,
5065    def_opersize_64=64,
5066    opcode=[0x0F, 0xD7],
5067    operands=[Operand(type="Reg", size=64, dest="Spare"),
5068              Operand(type="SIMDReg", size=64, dest="EA")])
5069add_group("pmovmskb",
5070    suffix="q",
5071    cpu=["SSE2"],
5072    modifiers=["SetVEX"],
5073    opersize=64,
5074    def_opersize_64=64,
5075    prefix=0x66,
5076    opcode=[0x0F, 0xD7],
5077    operands=[Operand(type="Reg", size=64, dest="Spare"),
5078              Operand(type="SIMDReg", size=128, dest="EA")])
5079add_group("pmovmskb",
5080    suffix="q",
5081    cpu=["SSE2"],
5082    vex=256,
5083    opersize=64,
5084    def_opersize_64=64,
5085    prefix=0x66,
5086    opcode=[0x0F, 0xD7],
5087    operands=[Operand(type="Reg", size=64, dest="Spare"),
5088              Operand(type="SIMDReg", size=256, dest="EA")])
5089
5090add_insn("pmovmskb", "pmovmskb")
5091add_insn("vpmovmskb", "pmovmskb", modifiers=[VEXL0], avx=True)
5092
5093add_group("pshufw",
5094    cpu=["MMX", "P3"],
5095    opcode=[0x0F, 0x70],
5096    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
5097              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
5098              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5099
5100add_insn("pshufw", "pshufw")
5101
5102#####################################################################
5103# SSE2 instructions
5104#####################################################################
5105add_group("xmm_xmm64",
5106    cpu=["SSE2"],
5107    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5108    prefix=0x00,
5109    opcode=[0x0F, 0x00],
5110    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5111              Operand(type="SIMDReg", size=128, dest="EA")])
5112add_group("xmm_xmm64",
5113    cpu=["SSE2"],
5114    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5115    prefix=0x00,
5116    opcode=[0x0F, 0x00],
5117    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5118              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5119add_group("xmm_xmm64",
5120    cpu=["AVX"],
5121    modifiers=["PreAdd", "Op1Add"],
5122    vex=128,
5123    prefix=0x00,
5124    opcode=[0x0F, 0x00],
5125    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5126              Operand(type="SIMDReg", size=128, dest="VEX"),
5127              Operand(type="SIMDReg", size=128, dest="EA")])
5128add_group("xmm_xmm64",
5129    cpu=["AVX"],
5130    modifiers=["PreAdd", "Op1Add"],
5131    vex=128,
5132    prefix=0x00,
5133    opcode=[0x0F, 0x00],
5134    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5135              Operand(type="SIMDReg", size=128, dest="VEX"),
5136              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5137
5138add_insn("addsd",    "xmm_xmm64", modifiers=[0xF2, 0x58])
5139add_insn("comisd",   "xmm_xmm64", modifiers=[0x66, 0x2F])
5140add_insn("cvtdq2pd", "xmm_xmm64", modifiers=[0xF3, 0xE6])
5141add_insn("cvtps2pd", "xmm_xmm64", modifiers=[0, 0x5A])
5142add_insn("cvtsd2ss", "xmm_xmm64", modifiers=[0xF2, 0x5A])
5143add_insn("divsd",    "xmm_xmm64", modifiers=[0xF2, 0x5E])
5144add_insn("maxsd",    "xmm_xmm64", modifiers=[0xF2, 0x5F])
5145add_insn("minsd",    "xmm_xmm64", modifiers=[0xF2, 0x5D])
5146add_insn("mulsd",    "xmm_xmm64", modifiers=[0xF2, 0x59])
5147add_insn("subsd",    "xmm_xmm64", modifiers=[0xF2, 0x5C])
5148add_insn("sqrtsd",   "xmm_xmm64", modifiers=[0xF2, 0x51])
5149add_insn("ucomisd",  "xmm_xmm64", modifiers=[0x66, 0x2E])
5150
5151add_insn("vaddsd",    "xmm_xmm64", modifiers=[0xF2, 0x58, VEXL0], avx=True)
5152# vcomisd and vucomisd are only two operand
5153# vcvtdq2pd and vcvtps2pd can take ymm, xmm version
5154add_insn("vcvtsd2ss", "xmm_xmm64", modifiers=[0xF2, 0x5A, VEXL0], avx=True)
5155add_insn("vdivsd",    "xmm_xmm64", modifiers=[0xF2, 0x5E, VEXL0], avx=True)
5156add_insn("vmaxsd",    "xmm_xmm64", modifiers=[0xF2, 0x5F, VEXL0], avx=True)
5157add_insn("vminsd",    "xmm_xmm64", modifiers=[0xF2, 0x5D, VEXL0], avx=True)
5158add_insn("vmulsd",    "xmm_xmm64", modifiers=[0xF2, 0x59, VEXL0], avx=True)
5159add_insn("vsubsd",    "xmm_xmm64", modifiers=[0xF2, 0x5C, VEXL0], avx=True)
5160add_insn("vsqrtsd",   "xmm_xmm64", modifiers=[0xF2, 0x51, VEXL0], avx=True)
5161
5162add_insn("addpd",    "xmm_xmm128", modifiers=[0x66, 0x58], cpu=["SSE2"])
5163add_insn("andnpd",   "xmm_xmm128", modifiers=[0x66, 0x55], cpu=["SSE2"])
5164add_insn("andpd",    "xmm_xmm128", modifiers=[0x66, 0x54], cpu=["SSE2"])
5165add_insn("cvtdq2ps", "xmm_xmm128", modifiers=[0, 0x5B], cpu=["SSE2"])
5166add_insn("cvtpd2dq", "xmm_xmm128", modifiers=[0xF2, 0xE6], cpu=["SSE2"])
5167add_insn("cvtpd2ps", "xmm_xmm128", modifiers=[0x66, 0x5A], cpu=["SSE2"])
5168add_insn("cvtps2dq", "xmm_xmm128", modifiers=[0x66, 0x5B], cpu=["SSE2"])
5169add_insn("divpd",    "xmm_xmm128", modifiers=[0x66, 0x5E], cpu=["SSE2"])
5170add_insn("maxpd",    "xmm_xmm128", modifiers=[0x66, 0x5F], cpu=["SSE2"])
5171add_insn("minpd",    "xmm_xmm128", modifiers=[0x66, 0x5D], cpu=["SSE2"])
5172add_insn("mulpd",    "xmm_xmm128", modifiers=[0x66, 0x59], cpu=["SSE2"])
5173add_insn("orpd",     "xmm_xmm128", modifiers=[0x66, 0x56], cpu=["SSE2"])
5174add_insn("sqrtpd",   "xmm_xmm128", modifiers=[0x66, 0x51], cpu=["SSE2"])
5175add_insn("subpd",    "xmm_xmm128", modifiers=[0x66, 0x5C], cpu=["SSE2"])
5176add_insn("unpckhpd", "xmm_xmm128", modifiers=[0x66, 0x15], cpu=["SSE2"])
5177add_insn("unpcklpd", "xmm_xmm128", modifiers=[0x66, 0x14], cpu=["SSE2"])
5178add_insn("xorpd",    "xmm_xmm128", modifiers=[0x66, 0x57], cpu=["SSE2"])
5179
5180add_insn("vaddpd",    "xmm_xmm128_256", modifiers=[0x66, 0x58, VEXL0], avx=True)
5181add_insn("vandnpd",   "xmm_xmm128_256", modifiers=[0x66, 0x55, VEXL0], avx=True)
5182add_insn("vandpd",    "xmm_xmm128_256", modifiers=[0x66, 0x54, VEXL0], avx=True)
5183# vcvtdq2ps and vcvtps2dq are 2-operand, YMM capable
5184# vcvtpd2dq and vcvtpd2ps take xmm, ymm combination
5185add_insn("vdivpd",    "xmm_xmm128_256", modifiers=[0x66, 0x5E, VEXL0], avx=True)
5186add_insn("vmaxpd",    "xmm_xmm128_256", modifiers=[0x66, 0x5F, VEXL0], avx=True)
5187add_insn("vminpd",    "xmm_xmm128_256", modifiers=[0x66, 0x5D, VEXL0], avx=True)
5188add_insn("vmulpd",    "xmm_xmm128_256", modifiers=[0x66, 0x59, VEXL0], avx=True)
5189add_insn("vorpd",     "xmm_xmm128_256", modifiers=[0x66, 0x56, VEXL0], avx=True)
5190# vsqrtpd doesn't add third operand
5191add_insn("vsubpd",    "xmm_xmm128_256", modifiers=[0x66, 0x5C, VEXL0], avx=True)
5192add_insn("vunpckhpd", "xmm_xmm128_256", modifiers=[0x66, 0x15, VEXL0], avx=True)
5193add_insn("vunpcklpd", "xmm_xmm128_256", modifiers=[0x66, 0x14, VEXL0], avx=True)
5194add_insn("vxorpd",    "xmm_xmm128_256", modifiers=[0x66, 0x57, VEXL0], avx=True)
5195
5196add_group("ssecmp_64",
5197    cpu=["SSE2"],
5198    modifiers=["Imm8", "PreAdd", "SetVEX"],
5199    prefix=0x00,
5200    opcode=[0x0F, 0xC2],
5201    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5202              Operand(type="SIMDReg", size=128, dest="EA")])
5203add_group("ssecmp_64",
5204    cpu=["SSE2"],
5205    modifiers=["Imm8", "PreAdd", "SetVEX"],
5206    prefix=0x00,
5207    opcode=[0x0F, 0xC2],
5208    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5209              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5210add_group("ssecmp_64",
5211    cpu=["AVX"],
5212    modifiers=["Imm8", "PreAdd"],
5213    vex=128,
5214    prefix=0x00,
5215    opcode=[0x0F, 0xC2],
5216    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5217              Operand(type="SIMDReg", size=128, dest="VEX"),
5218              Operand(type="SIMDReg", size=128, dest="EA")])
5219add_group("ssecmp_64",
5220    cpu=["AVX"],
5221    modifiers=["Imm8", "PreAdd"],
5222    vex=128,
5223    prefix=0x00,
5224    opcode=[0x0F, 0xC2],
5225    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5226              Operand(type="SIMDReg", size=128, dest="VEX"),
5227              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5228
5229for ib, cc in ssecoms:
5230    add_insn("cmp"+cc+"sd", "ssecmp_64", modifiers=[ib, 0xF2])
5231    add_insn("cmp"+cc+"pd", "ssecmp_128", modifiers=[ib, 0x66])
5232
5233for ib, cc in avxcoms:
5234    add_insn("vcmp"+cc+"sd", "ssecmp_64", modifiers=[ib, 0xF2, VEXL0], avx=True)
5235    add_insn("vcmp"+cc+"pd", "ssecmp_128", modifiers=[ib, 0x66, VEXL0], avx=True)
5236
5237add_insn("cmppd",  "xmm_xmm128_imm", modifiers=[0x66, 0xC2], cpu=["SSE2"])
5238add_insn("shufpd", "xmm_xmm128_imm", modifiers=[0x66, 0xC6], cpu=["SSE2"])
5239add_insn("vcmppd",  "xmm_xmm128_imm_256", modifiers=[0x66, 0xC2, VEXL0], avx=True)
5240add_insn("vshufpd", "xmm_xmm128_imm_256", modifiers=[0x66, 0xC6, VEXL0], avx=True)
5241
5242add_insn("cvtsi2sd", "cvt_xmm_rmx", modifiers=[0xF2, 0x2A], cpu=["SSE2"])
5243add_insn("vcvtsi2sd", "cvt_xmm_rmx", modifiers=[0xF2, 0x2A, VEXL0], avx=True)
5244
5245add_group("cvt_rx_xmm64",
5246    suffix="l",
5247    cpu=["SSE2"],
5248    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5249    prefix=0x00,
5250    opcode=[0x0F, 0x00],
5251    operands=[Operand(type="Reg", size=32, dest="Spare"),
5252              Operand(type="SIMDReg", size=128, dest="EA")])
5253add_group("cvt_rx_xmm64",
5254    suffix="l",
5255    cpu=["SSE2"],
5256    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5257    prefix=0x00,
5258    opcode=[0x0F, 0x00],
5259    operands=[Operand(type="Reg", size=32, dest="Spare"),
5260              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5261# REX
5262add_group("cvt_rx_xmm64",
5263    suffix="q",
5264    cpu=["SSE2"],
5265    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5266    opersize=64,
5267    prefix=0x00,
5268    opcode=[0x0F, 0x00],
5269    operands=[Operand(type="Reg", size=64, dest="Spare"),
5270              Operand(type="SIMDReg", size=128, dest="EA")])
5271add_group("cvt_rx_xmm64",
5272    suffix="q",
5273    cpu=["SSE2"],
5274    modifiers=["PreAdd", "Op1Add", "SetVEX"],
5275    opersize=64,
5276    prefix=0x00,
5277    opcode=[0x0F, 0x00],
5278    operands=[Operand(type="Reg", size=64, dest="Spare"),
5279              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5280
5281add_insn("cvtsd2si", "cvt_rx_xmm64", modifiers=[0xF2, 0x2D])
5282add_insn("vcvtsd2si", "cvt_rx_xmm64", modifiers=[0xF2, 0x2D, VEXL0], avx=True)
5283
5284add_group("cvt_mm_xmm",
5285    cpu=["SSE2"],
5286    modifiers=["PreAdd", "Op1Add"],
5287    prefix=0x00,
5288    opcode=[0x0F, 0x00],
5289    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
5290              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
5291
5292add_insn("cvtpd2pi", "cvt_mm_xmm", modifiers=[0x66, 0x2D], cpu=["SSE2"])
5293
5294add_group("cvt_xmm_mm_ss",
5295    cpu=["SSE"],
5296    modifiers=["PreAdd", "Op1Add"],
5297    prefix=0x00,
5298    opcode=[0x0F, 0x00],
5299    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5300              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
5301
5302add_insn("cvtpi2pd", "cvt_xmm_mm_ss", modifiers=[0x66, 0x2A], cpu=["SSE2"])
5303
5304# cmpsd SSE2 form
5305add_group("cmpsd",
5306    cpu=["SSE2"],
5307    modifiers=["SetVEX"],
5308    prefix=0xF2,
5309    opcode=[0x0F, 0xC2],
5310    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5311              Operand(type="SIMDReg", size=128, dest="EA"),
5312              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5313add_group("cmpsd",
5314    cpu=["SSE2"],
5315    modifiers=["SetVEX"],
5316    prefix=0xF2,
5317    opcode=[0x0F, 0xC2],
5318    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5319              Operand(type="Mem", size=64, relaxed=True, dest="EA"),
5320              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5321add_group("cmpsd",
5322    cpu=["AVX"],
5323    vex=128,
5324    prefix=0xF2,
5325    opcode=[0x0F, 0xC2],
5326    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5327              Operand(type="SIMDReg", size=128, dest="VEX"),
5328              Operand(type="SIMDReg", size=128, dest="EA"),
5329              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5330add_group("cmpsd",
5331    cpu=["AVX"],
5332    vex=128,
5333    prefix=0xF2,
5334    opcode=[0x0F, 0xC2],
5335    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5336              Operand(type="SIMDReg", size=128, dest="VEX"),
5337              Operand(type="Mem", size=64, relaxed=True, dest="EA"),
5338              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5339
5340# cmpsd is added in string instructions above, so don't re-add_insn()
5341add_insn("vcmpsd", "cmpsd", modifiers=[VEXL0], avx=True)
5342
5343add_insn("movapd", "movau", modifiers=[0x66, 0x28, 0x01], cpu=["SSE2"])
5344add_insn("movupd", "movau", modifiers=[0x66, 0x10, 0x01], cpu=["SSE2"])
5345add_insn("vmovapd", "movau", modifiers=[0x66, 0x28, 0x01], avx=True)
5346add_insn("vmovupd", "movau", modifiers=[0x66, 0x10, 0x01], avx=True)
5347
5348add_insn("movhpd", "movhlp", modifiers=[0x66, 0x16], cpu=["SSE2"])
5349add_insn("movlpd", "movhlp", modifiers=[0x66, 0x12], cpu=["SSE2"])
5350add_insn("vmovhpd", "movhlp", modifiers=[0x66, 0x16, VEXL0], avx=True)
5351add_insn("vmovlpd", "movhlp", modifiers=[0x66, 0x12, VEXL0], avx=True)
5352
5353add_insn("movmskpd", "movmsk", modifiers=[0x66], cpu=["SSE2"])
5354add_insn("vmovmskpd", "movmsk", modifiers=[0x66, VEXL0], avx=True)
5355
5356add_insn("movntpd", "movnt", modifiers=[0x66, 0x2B], cpu=["SSE2"])
5357add_insn("movntdq", "movnt", modifiers=[0x66, 0xE7], cpu=["SSE2"])
5358add_insn("vmovntpd", "movnt", modifiers=[0x66, 0x2B, VEXL0], avx=True)
5359add_insn("vmovntdq", "movnt", modifiers=[0x66, 0xE7, VEXL0], avx=True)
5360
5361# movsd SSE2 forms
5362add_group("movsd",
5363    cpu=["SSE2"],
5364    modifiers=["SetVEX"],
5365    prefix=0xF2,
5366    opcode=[0x0F, 0x10],
5367    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5368              Operand(type="SIMDReg", size=128, dest="EA")])
5369add_group("movsd",
5370    cpu=["SSE2"],
5371    modifiers=["SetVEX"],
5372    prefix=0xF2,
5373    opcode=[0x0F, 0x10],
5374    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5375              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5376add_group("movsd",
5377    cpu=["SSE2"],
5378    modifiers=["SetVEX"],
5379    prefix=0xF2,
5380    opcode=[0x0F, 0x11],
5381    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
5382              Operand(type="SIMDReg", size=128, dest="Spare")])
5383add_group("movsd",
5384    cpu=["AVX"],
5385    vex=128,
5386    prefix=0xF2,
5387    opcode=[0x0F, 0x10],
5388    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5389              Operand(type="SIMDReg", size=128, dest="VEX"),
5390              Operand(type="SIMDReg", size=128, dest="EA")])
5391# movsd is added in string instructions above, so don't re-add_insn()
5392add_insn("vmovsd", "movsd", modifiers=[VEXL0], avx=True)
5393
5394#####################################################################
5395# P4 VMX Instructions
5396#####################################################################
5397
5398add_group("eptvpid",
5399    modifiers=["Op2Add"],
5400    suffix="l",
5401    not64=True,
5402    cpu=["EPTVPID"],
5403    opersize=32,
5404    prefix=0x66,
5405    opcode=[0x0F, 0x38, 0x80],
5406    operands=[Operand(type="Reg", size=32, dest="Spare"),
5407              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
5408add_group("eptvpid",
5409    modifiers=["Op2Add"],
5410    suffix="q",
5411    cpu=["EPTVPID"],
5412    opersize=64,
5413    prefix=0x66,
5414    opcode=[0x0F, 0x38, 0x80],
5415    operands=[Operand(type="Reg", size=64, dest="Spare"),
5416              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
5417add_insn("invept", "eptvpid", modifiers=[0])
5418add_insn("invvpid", "eptvpid", modifiers=[1])
5419
5420add_insn("vmcall", "threebyte", modifiers=[0x0F, 0x01, 0xC1], cpu=["P4"])
5421add_insn("vmlaunch", "threebyte", modifiers=[0x0F, 0x01, 0xC2], cpu=["P4"])
5422add_insn("vmresume", "threebyte", modifiers=[0x0F, 0x01, 0xC3], cpu=["P4"])
5423add_insn("vmxoff", "threebyte", modifiers=[0x0F, 0x01, 0xC4], cpu=["P4"])
5424
5425add_group("vmxmemrd",
5426    suffix="l",
5427    not64=True,
5428    cpu=["P4"],
5429    opersize=32,
5430    opcode=[0x0F, 0x78],
5431    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
5432              Operand(type="Reg", size=32, dest="Spare")])
5433add_group("vmxmemrd",
5434    suffix="q",
5435    cpu=["P4"],
5436    opersize=64,
5437    def_opersize_64=64,
5438    opcode=[0x0F, 0x78],
5439    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
5440              Operand(type="Reg", size=64, dest="Spare")])
5441add_insn("vmread", "vmxmemrd")
5442
5443add_group("vmxmemwr",
5444    suffix="l",
5445    not64=True,
5446    cpu=["P4"],
5447    opersize=32,
5448    opcode=[0x0F, 0x79],
5449    operands=[Operand(type="Reg", size=32, dest="Spare"),
5450              Operand(type="RM", size=32, relaxed=True, dest="EA")])
5451add_group("vmxmemwr",
5452    suffix="q",
5453    cpu=["P4"],
5454    opersize=64,
5455    def_opersize_64=64,
5456    opcode=[0x0F, 0x79],
5457    operands=[Operand(type="Reg", size=64, dest="Spare"),
5458              Operand(type="RM", size=64, relaxed=True, dest="EA")])
5459add_insn("vmwrite", "vmxmemwr")
5460
5461add_group("vmxtwobytemem",
5462    modifiers=["SpAdd"],
5463    cpu=["P4"],
5464    opcode=[0x0F, 0xC7],
5465    spare=0,
5466    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5467add_insn("vmptrld", "vmxtwobytemem", modifiers=[6])
5468add_insn("vmptrst", "vmxtwobytemem", modifiers=[7])
5469
5470add_group("vmxthreebytemem",
5471    modifiers=["PreAdd"],
5472    cpu=["P4"],
5473    prefix=0x00,
5474    opcode=[0x0F, 0xC7],
5475    spare=6,
5476    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA")])
5477add_insn("vmclear", "vmxthreebytemem", modifiers=[0x66])
5478add_insn("vmxon", "vmxthreebytemem", modifiers=[0xF3])
5479
5480#####################################################################
5481# Intel SMX Instructions
5482#####################################################################
5483add_insn("getsec", "twobyte", modifiers=[0x0F, 0x37], cpu=["SMX"])
5484
5485add_insn("cvttpd2pi", "cvt_mm_xmm", modifiers=[0x66, 0x2C], cpu=["SSE2"])
5486add_insn("cvttsd2si", "cvt_rx_xmm64", modifiers=[0xF2, 0x2C], cpu=["SSE2"])
5487add_insn("cvttpd2dq", "xmm_xmm128", modifiers=[0x66, 0xE6], cpu=["SSE2"])
5488add_insn("cvttps2dq", "xmm_xmm128", modifiers=[0xF3, 0x5B], cpu=["SSE2"])
5489add_insn("pmuludq", "mmxsse2", modifiers=[0xF4], cpu=["SSE2"])
5490add_insn("pshufd", "xmm_xmm128_imm", modifiers=[0x66, 0x70], cpu=["SSE2"])
5491add_insn("pshufhw", "xmm_xmm128_imm", modifiers=[0xF3, 0x70], cpu=["SSE2"])
5492add_insn("pshuflw", "xmm_xmm128_imm", modifiers=[0xF2, 0x70], cpu=["SSE2"])
5493add_insn("punpckhqdq", "xmm_xmm128", modifiers=[0x66, 0x6D], cpu=["SSE2"])
5494add_insn("punpcklqdq", "xmm_xmm128", modifiers=[0x66, 0x6C], cpu=["SSE2"])
5495
5496add_insn("vcvttsd2si", "cvt_rx_xmm64", modifiers=[0xF2, 0x2C, VEXL0], avx=True)
5497# vcvttpd2dq takes xmm, ymm combination
5498# vcvttps2dq is two-operand
5499add_insn("vpmuludq", "xmm_xmm128_256avx2", modifiers=[0x66, 0xF4, VEXL0], avx=True)
5500add_insn("vpshufd", "xmm_xmm128_imm_256avx2", modifiers=[0x66, 0x70, VEXL0], avx=True)
5501add_insn("vpshufhw", "xmm_xmm128_imm_256avx2", modifiers=[0xF3, 0x70, VEXL0], avx=True)
5502add_insn("vpshuflw", "xmm_xmm128_imm_256avx2", modifiers=[0xF2, 0x70, VEXL0], avx=True)
5503add_insn("vpunpckhqdq", "xmm_xmm128_256avx2", modifiers=[0x66, 0x6D, VEXL0], avx=True)
5504add_insn("vpunpcklqdq", "xmm_xmm128_256avx2", modifiers=[0x66, 0x6C, VEXL0], avx=True)
5505
5506add_insn("cvtss2sd", "xmm_xmm32", modifiers=[0xF3, 0x5A], cpu=["SSE2"])
5507add_insn("vcvtss2sd", "xmm_xmm32", modifiers=[0xF3, 0x5A, VEXL0], avx=True)
5508
5509add_group("maskmovdqu",
5510    cpu=["SSE2"],
5511    modifiers=["SetVEX"],
5512    prefix=0x66,
5513    opcode=[0x0F, 0xF7],
5514    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5515              Operand(type="SIMDReg", size=128, dest="EA")])
5516
5517add_insn("maskmovdqu", "maskmovdqu")
5518add_insn("vmaskmovdqu", "maskmovdqu", modifiers=[VEXL0], avx=True)
5519
5520add_insn("movdqa", "movau", modifiers=[0x66, 0x6F, 0x10], cpu=["SSE2"])
5521add_insn("movdqu", "movau", modifiers=[0xF3, 0x6F, 0x10], cpu=["SSE2"])
5522add_insn("vmovdqa", "movau", modifiers=[0x66, 0x6F, 0x10], avx=True)
5523add_insn("vmovdqu", "movau", modifiers=[0xF3, 0x6F, 0x10], avx=True)
5524
5525add_group("movdq2q",
5526    cpu=["SSE2"],
5527    prefix=0xF2,
5528    opcode=[0x0F, 0xD6],
5529    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
5530              Operand(type="SIMDReg", size=128, dest="EA")])
5531
5532add_insn("movdq2q", "movdq2q")
5533
5534add_group("movq2dq",
5535    cpu=["SSE2"],
5536    prefix=0xF3,
5537    opcode=[0x0F, 0xD6],
5538    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5539              Operand(type="SIMDReg", size=64, dest="EA")])
5540
5541add_insn("movq2dq", "movq2dq")
5542
5543add_group("pslrldq",
5544    cpu=["SSE2"],
5545    modifiers=["SpAdd", "SetVEX"],
5546    prefix=0x66,
5547    opcode=[0x0F, 0x73],
5548    spare=0,
5549    operands=[Operand(type="SIMDReg", size=128, dest="EAVEX"),
5550              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5551add_group("pslrldq",
5552    cpu=["SSE2"],
5553    modifiers=["SpAdd", "SetVEX"],
5554    prefix=0x66,
5555    opcode=[0x0F, 0x73],
5556    spare=0,
5557    operands=[Operand(type="SIMDReg", size=128, dest="VEX"),
5558              Operand(type="SIMDReg", size=128, dest="EA"),
5559              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5560add_group("pslrldq",
5561    cpu=["AVX2"],
5562    modifiers=["SpAdd"],
5563    vex=256,
5564    prefix=0x66,
5565    opcode=[0x0F, 0x73],
5566    spare=0,
5567    operands=[Operand(type="SIMDReg", size=256, dest="EAVEX"),
5568              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5569add_group("pslrldq",
5570    cpu=["AVX2"],
5571    modifiers=["SpAdd"],
5572    vex=256,
5573    prefix=0x66,
5574    opcode=[0x0F, 0x73],
5575    spare=0,
5576    operands=[Operand(type="SIMDReg", size=256, dest="VEX"),
5577              Operand(type="SIMDReg", size=256, dest="EA"),
5578              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5579
5580add_insn("pslldq", "pslrldq", modifiers=[7])
5581add_insn("psrldq", "pslrldq", modifiers=[3])
5582add_insn("vpslldq", "pslrldq", modifiers=[7, VEXL0], avx=True)
5583add_insn("vpsrldq", "pslrldq", modifiers=[3, VEXL0], avx=True)
5584
5585#####################################################################
5586# SSE3 / PNI Prescott New Instructions instructions
5587#####################################################################
5588add_insn("addsubpd", "xmm_xmm128", modifiers=[0x66, 0xD0], cpu=["SSE3"])
5589add_insn("addsubps", "xmm_xmm128", modifiers=[0xF2, 0xD0], cpu=["SSE3"])
5590add_insn("haddpd",   "xmm_xmm128", modifiers=[0x66, 0x7C], cpu=["SSE3"])
5591add_insn("haddps",   "xmm_xmm128", modifiers=[0xF2, 0x7C], cpu=["SSE3"])
5592add_insn("hsubpd",   "xmm_xmm128", modifiers=[0x66, 0x7D], cpu=["SSE3"])
5593add_insn("hsubps",   "xmm_xmm128", modifiers=[0xF2, 0x7D], cpu=["SSE3"])
5594
5595add_insn("vaddsubpd", "xmm_xmm128_256", modifiers=[0x66, 0xD0, VEXL0], avx=True)
5596add_insn("vaddsubps", "xmm_xmm128_256", modifiers=[0xF2, 0xD0, VEXL0], avx=True)
5597add_insn("vhaddpd",   "xmm_xmm128_256", modifiers=[0x66, 0x7C, VEXL0], avx=True)
5598add_insn("vhaddps",   "xmm_xmm128_256", modifiers=[0xF2, 0x7C, VEXL0], avx=True)
5599add_insn("vhsubpd",   "xmm_xmm128_256", modifiers=[0x66, 0x7D, VEXL0], avx=True)
5600add_insn("vhsubps",   "xmm_xmm128_256", modifiers=[0xF2, 0x7D, VEXL0], avx=True)
5601
5602add_insn("movshdup", "xmm_xmm128", modifiers=[0xF3, 0x16], cpu=["SSE3"])
5603add_insn("movsldup", "xmm_xmm128", modifiers=[0xF3, 0x12], cpu=["SSE3"])
5604add_insn("fisttp",   "fildstp", modifiers=[1, 0, 1], cpu=["SSE3"])
5605add_insn("fisttpll", "fildstp", suffix="q", modifiers=[7], cpu=["SSE3"])
5606add_insn("movddup", "xmm_xmm64", modifiers=[0xF2, 0x12], cpu=["SSE3"])
5607add_insn("monitor", "threebyte", modifiers=[0x0F, 0x01, 0xC8], cpu=["SSE3"])
5608add_insn("mwait",   "threebyte", modifiers=[0x0F, 0x01, 0xC9], cpu=["SSE3"])
5609
5610add_group("lddqu",
5611    cpu=["SSE3"],
5612    modifiers=["SetVEX"],
5613    prefix=0xF2,
5614    opcode=[0x0F, 0xF0],
5615    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5616              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
5617add_group("lddqu",
5618    cpu=["AVX"],
5619    vex=256,
5620    prefix=0xF2,
5621    opcode=[0x0F, 0xF0],
5622    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5623              Operand(type="Mem", size=256, relaxed=True, dest="EA")])
5624
5625add_insn("lddqu", "lddqu")
5626add_insn("vlddqu", "lddqu", modifiers=[VEXL0], avx=True)
5627
5628#####################################################################
5629# SSSE3 / TNI Tejas New Intructions instructions
5630#####################################################################
5631
5632add_group("ssse3",
5633    cpu=["SSSE3"],
5634    notavx=True,
5635    modifiers=["Op2Add"],
5636    opcode=[0x0F, 0x38, 0x00],
5637    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
5638              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
5639add_group("ssse3",
5640    cpu=["SSSE3"],
5641    modifiers=["Op2Add", "SetVEX"],
5642    prefix=0x66,
5643    opcode=[0x0F, 0x38, 0x00],
5644    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5645              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
5646add_group("ssse3",
5647    cpu=["AVX"],
5648    modifiers=["Op2Add"],
5649    vex=128,
5650    prefix=0x66,
5651    opcode=[0x0F, 0x38, 0x00],
5652    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5653              Operand(type="SIMDReg", size=128, dest="VEX"),
5654              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
5655add_group("ssse3",
5656    cpu=["AVX2"],
5657    modifiers=["Op2Add"],
5658    vex=256,
5659    prefix=0x66,
5660    opcode=[0x0F, 0x38, 0x00],
5661    operands=[Operand(type="SIMDReg", size=256, dest="SpareVEX"),
5662              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
5663add_group("ssse3",
5664    cpu=["AVX2"],
5665    modifiers=["Op2Add"],
5666    vex=256,
5667    prefix=0x66,
5668    opcode=[0x0F, 0x38, 0x00],
5669    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5670              Operand(type="SIMDReg", size=256, dest="VEX"),
5671              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
5672
5673add_insn("pshufb",    "ssse3", modifiers=[0x00])
5674add_insn("phaddw",    "ssse3", modifiers=[0x01])
5675add_insn("phaddd",    "ssse3", modifiers=[0x02])
5676add_insn("phaddsw",   "ssse3", modifiers=[0x03])
5677add_insn("pmaddubsw", "ssse3", modifiers=[0x04])
5678add_insn("phsubw",    "ssse3", modifiers=[0x05])
5679add_insn("phsubd",    "ssse3", modifiers=[0x06])
5680add_insn("phsubsw",   "ssse3", modifiers=[0x07])
5681add_insn("psignb",    "ssse3", modifiers=[0x08])
5682add_insn("psignw",    "ssse3", modifiers=[0x09])
5683add_insn("psignd",    "ssse3", modifiers=[0x0A])
5684add_insn("pmulhrsw",  "ssse3", modifiers=[0x0B])
5685add_insn("pabsb",     "ssse3", modifiers=[0x1C])
5686add_insn("pabsw",     "ssse3", modifiers=[0x1D])
5687add_insn("pabsd",     "ssse3", modifiers=[0x1E])
5688
5689add_insn("vpshufb",    "ssse3", modifiers=[0x00, VEXL0], avx=True)
5690add_insn("vphaddw",    "ssse3", modifiers=[0x01, VEXL0], avx=True)
5691add_insn("vphaddd",    "ssse3", modifiers=[0x02, VEXL0], avx=True)
5692add_insn("vphaddsw",   "ssse3", modifiers=[0x03, VEXL0], avx=True)
5693add_insn("vpmaddubsw", "ssse3", modifiers=[0x04, VEXL0], avx=True)
5694add_insn("vphsubw",    "ssse3", modifiers=[0x05, VEXL0], avx=True)
5695add_insn("vphsubd",    "ssse3", modifiers=[0x06, VEXL0], avx=True)
5696add_insn("vphsubsw",   "ssse3", modifiers=[0x07, VEXL0], avx=True)
5697add_insn("vpsignb",    "ssse3", modifiers=[0x08, VEXL0], avx=True)
5698add_insn("vpsignw",    "ssse3", modifiers=[0x09, VEXL0], avx=True)
5699add_insn("vpsignd",    "ssse3", modifiers=[0x0A, VEXL0], avx=True)
5700add_insn("vpmulhrsw",  "ssse3", modifiers=[0x0B, VEXL0], avx=True)
5701# vpabsb/vpabsw/vpabsd are 2 operand only
5702
5703add_group("ssse3imm",
5704    cpu=["SSSE3"],
5705    modifiers=["Op2Add"],
5706    opcode=[0x0F, 0x3A, 0x00],
5707    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
5708              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA"),
5709              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5710add_group("ssse3imm",
5711    cpu=["SSSE3"],
5712    modifiers=["Op2Add"],
5713    prefix=0x66,
5714    opcode=[0x0F, 0x3A, 0x00],
5715    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5716              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5717              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5718
5719add_insn("palignr", "ssse3imm", modifiers=[0x0F])
5720add_insn("vpalignr", "sse4imm_256avx2", modifiers=[0x0F, VEXL0], avx=True)
5721
5722#####################################################################
5723# SSE4.1 / SSE4.2 instructions
5724#####################################################################
5725
5726add_group("sse4",
5727    cpu=["SSE41"],
5728    modifiers=["Op2Add", "SetVEX"],
5729    prefix=0x66,
5730    opcode=[0x0F, 0x38, 0x00],
5731    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5732              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
5733add_group("sse4",
5734    cpu=["AVX"],
5735    modifiers=["Op2Add"],
5736    vex=256,
5737    prefix=0x66,
5738    opcode=[0x0F, 0x38, 0x00],
5739    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5740              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
5741
5742add_insn("packusdw",   "sse4", modifiers=[0x2B])
5743add_insn("pcmpeqq",    "sse4", modifiers=[0x29])
5744add_insn("pcmpgtq",    "sse4", modifiers=[0x37])
5745add_insn("phminposuw", "sse4", modifiers=[0x41])
5746add_insn("pmaxsb",     "sse4", modifiers=[0x3C])
5747add_insn("pmaxsd",     "sse4", modifiers=[0x3D])
5748add_insn("pmaxud",     "sse4", modifiers=[0x3F])
5749add_insn("pmaxuw",     "sse4", modifiers=[0x3E])
5750add_insn("pminsb",     "sse4", modifiers=[0x38])
5751add_insn("pminsd",     "sse4", modifiers=[0x39])
5752add_insn("pminud",     "sse4", modifiers=[0x3B])
5753add_insn("pminuw",     "sse4", modifiers=[0x3A])
5754add_insn("pmuldq",     "sse4", modifiers=[0x28])
5755add_insn("pmulld",     "sse4", modifiers=[0x40])
5756add_insn("ptest",      "sse4", modifiers=[0x17])
5757
5758# AVX versions use ssse3, and disable MMX version, as they're 3-operand
5759add_insn("vpackusdw",   "ssse3", modifiers=[0x2B, VEXL0], avx=True)
5760add_insn("vpcmpeqq",    "ssse3", modifiers=[0x29, VEXL0], avx=True)
5761add_insn("vpcmpgtq",    "ssse3", modifiers=[0x37, VEXL0], avx=True)
5762# vphminposuw is 2 operand only
5763add_insn("vpmaxsb",     "ssse3", modifiers=[0x3C, VEXL0], avx=True)
5764add_insn("vpmaxsd",     "ssse3", modifiers=[0x3D, VEXL0], avx=True)
5765add_insn("vpmaxud",     "ssse3", modifiers=[0x3F, VEXL0], avx=True)
5766add_insn("vpmaxuw",     "ssse3", modifiers=[0x3E, VEXL0], avx=True)
5767add_insn("vpminsb",     "ssse3", modifiers=[0x38, VEXL0], avx=True)
5768add_insn("vpminsd",     "ssse3", modifiers=[0x39, VEXL0], avx=True)
5769add_insn("vpminud",     "ssse3", modifiers=[0x3B, VEXL0], avx=True)
5770add_insn("vpminuw",     "ssse3", modifiers=[0x3A, VEXL0], avx=True)
5771add_insn("vpmuldq",     "ssse3", modifiers=[0x28, VEXL0], avx=True)
5772add_insn("vpmulld",     "ssse3", modifiers=[0x40, VEXL0], avx=True)
5773# vptest uses SSE4 style (2 operand only), and takes 256-bit operands
5774add_insn("vptest", "sse4", modifiers=[0x17, VEXL0], avx=True)
5775
5776add_group("sse4imm_256",
5777    cpu=["SSE41"],
5778    modifiers=["Op2Add", "SetVEX"],
5779    prefix=0x66,
5780    opcode=[0x0F, 0x3A, 0x00],
5781    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5782              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5783              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5784add_group("sse4imm_256",
5785    cpu=["AVX"],
5786    modifiers=["Op2Add"],
5787    vex=128,
5788    prefix=0x66,
5789    opcode=[0x0F, 0x3A, 0x00],
5790    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5791              Operand(type="SIMDReg", size=128, dest="VEX"),
5792              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5793              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5794add_group("sse4imm_256",
5795    cpu=["AVX"],
5796    modifiers=["Op2Add"],
5797    vex=256,
5798    prefix=0x66,
5799    opcode=[0x0F, 0x3A, 0x00],
5800    operands=[Operand(type="SIMDReg", size=256, dest="SpareVEX"),
5801              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5802              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5803add_group("sse4imm_256",
5804    cpu=["AVX"],
5805    modifiers=["Op2Add"],
5806    vex=256,
5807    prefix=0x66,
5808    opcode=[0x0F, 0x3A, 0x00],
5809    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5810              Operand(type="SIMDReg", size=256, dest="VEX"),
5811              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5812              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5813
5814# Same as above except AVX2 required for 256-bit.
5815add_group("sse4imm_256avx2",
5816    cpu=["SSE41"],
5817    modifiers=["Op2Add", "SetVEX"],
5818    prefix=0x66,
5819    opcode=[0x0F, 0x3A, 0x00],
5820    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5821              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5822              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5823add_group("sse4imm_256avx2",
5824    cpu=["AVX"],
5825    modifiers=["Op2Add"],
5826    vex=128,
5827    prefix=0x66,
5828    opcode=[0x0F, 0x3A, 0x00],
5829    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5830              Operand(type="SIMDReg", size=128, dest="VEX"),
5831              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5832              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5833add_group("sse4imm_256avx2",
5834    cpu=["AVX2"],
5835    modifiers=["Op2Add"],
5836    vex=256,
5837    prefix=0x66,
5838    opcode=[0x0F, 0x3A, 0x00],
5839    operands=[Operand(type="SIMDReg", size=256, dest="SpareVEX"),
5840              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5841              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5842add_group("sse4imm_256avx2",
5843    cpu=["AVX2"],
5844    modifiers=["Op2Add"],
5845    vex=256,
5846    prefix=0x66,
5847    opcode=[0x0F, 0x3A, 0x00],
5848    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5849              Operand(type="SIMDReg", size=256, dest="VEX"),
5850              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5851              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5852
5853# Version that does not allow YMM registers
5854add_group("sse4imm",
5855    cpu=["SSE41"],
5856    modifiers=["Op2Add", "SetVEX"],
5857    prefix=0x66,
5858    opcode=[0x0F, 0x3A, 0x00],
5859    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5860              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5861              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5862add_group("sse4imm",
5863    cpu=["AVX"],
5864    modifiers=["Op2Add"],
5865    vex=128,
5866    prefix=0x66,
5867    opcode=[0x0F, 0x3A, 0x00],
5868    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5869              Operand(type="SIMDReg", size=128, dest="VEX"),
5870              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5871              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5872
5873for sz in [32, 64]:
5874    add_group("sse4m%dimm" % sz,
5875        cpu=["SSE41"],
5876        modifiers=["Op2Add", "SetVEX"],
5877        prefix=0x66,
5878        opcode=[0x0F, 0x3A, 0x00],
5879        operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5880                  Operand(type="SIMDReg", size=128, dest="EA"),
5881                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5882    add_group("sse4m%dimm" % sz,
5883        cpu=["SSE41"],
5884        modifiers=["Op2Add", "SetVEX"],
5885        prefix=0x66,
5886        opcode=[0x0F, 0x3A, 0x00],
5887        operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
5888                  Operand(type="Mem", size=sz, relaxed=True, dest="EA"),
5889                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5890    add_group("sse4m%dimm" % sz,
5891        cpu=["AVX"],
5892        modifiers=["Op2Add"],
5893        vex=128,
5894        prefix=0x66,
5895        opcode=[0x0F, 0x3A, 0x00],
5896        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5897                  Operand(type="SIMDReg", size=128, dest="VEX"),
5898                  Operand(type="SIMDReg", size=128, dest="EA"),
5899                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5900    add_group("sse4m%dimm" % sz,
5901        cpu=["AVX"],
5902        modifiers=["Op2Add"],
5903        vex=128,
5904        prefix=0x66,
5905        opcode=[0x0F, 0x3A, 0x00],
5906        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5907                  Operand(type="SIMDReg", size=128, dest="VEX"),
5908                  Operand(type="Mem", size=sz, relaxed=True, dest="EA"),
5909                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
5910
5911add_insn("blendpd", "sse4imm", modifiers=[0x0D])
5912add_insn("blendps", "sse4imm", modifiers=[0x0C])
5913add_insn("dppd",    "sse4imm", modifiers=[0x41])
5914add_insn("dpps",    "sse4imm", modifiers=[0x40])
5915add_insn("mpsadbw", "sse4imm", modifiers=[0x42])
5916add_insn("pblendw", "sse4imm", modifiers=[0x0E])
5917add_insn("roundpd", "sse4imm", modifiers=[0x09])
5918add_insn("roundps", "sse4imm", modifiers=[0x08])
5919add_insn("roundsd", "sse4m64imm", modifiers=[0x0B])
5920add_insn("roundss", "sse4m32imm", modifiers=[0x0A])
5921
5922# vdppd does not allow YMM registers
5923# vmpsadbw and vpblendw do not allow YMM registers unless AVX2
5924add_insn("vblendpd", "sse4imm_256", modifiers=[0x0D, VEXL0], avx=True)
5925add_insn("vblendps", "sse4imm_256", modifiers=[0x0C, VEXL0], avx=True)
5926add_insn("vdppd",    "sse4imm", modifiers=[0x41, VEXL0], avx=True)
5927add_insn("vdpps",    "sse4imm_256", modifiers=[0x40, VEXL0], avx=True)
5928add_insn("vmpsadbw", "sse4imm_256avx2", modifiers=[0x42, VEXL0], avx=True)
5929add_insn("vpblendw", "sse4imm_256avx2", modifiers=[0x0E, VEXL0], avx=True)
5930# vroundpd and vroundps don't add another register operand
5931add_insn("vroundsd", "sse4m64imm", modifiers=[0x0B, VEXL0], avx=True)
5932add_insn("vroundss", "sse4m32imm", modifiers=[0x0A, VEXL0], avx=True)
5933
5934add_group("sse4xmm0",
5935    cpu=["SSE41"],
5936    modifiers=["Op2Add"],
5937    prefix=0x66,
5938    opcode=[0x0F, 0x38, 0x00],
5939    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5940              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
5941add_group("sse4xmm0",
5942    cpu=["SSE41"],
5943    modifiers=["Op2Add"],
5944    prefix=0x66,
5945    opcode=[0x0F, 0x38, 0x00],
5946    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5947              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5948              Operand(type="XMM0", size=128, dest=None)])
5949
5950add_insn("blendvpd", "sse4xmm0", modifiers=[0x15])
5951add_insn("blendvps", "sse4xmm0", modifiers=[0x14])
5952add_insn("pblendvb", "sse4xmm0", modifiers=[0x10])
5953
5954# implicit XMM0 can't be VEX-encoded
5955add_group("avx_sse4xmm0",
5956    cpu=["AVX"],
5957    modifiers=["Op2Add"],
5958    vex=128,
5959    prefix=0x66,
5960    opcode=[0x0F, 0x3A, 0x00],
5961    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5962              Operand(type="SIMDReg", size=128, dest="VEX"),
5963              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5964              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
5965add_group("avx_sse4xmm0",
5966    cpu=["AVX"],
5967    modifiers=["Op2Add"],
5968    vex=256,
5969    prefix=0x66,
5970    opcode=[0x0F, 0x3A, 0x00],
5971    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5972              Operand(type="SIMDReg", size=256, dest="VEX"),
5973              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5974              Operand(type="SIMDReg", size=256, dest="VEXImmSrc")])
5975
5976add_insn("vblendvpd", "avx_sse4xmm0", modifiers=[0x4B])
5977add_insn("vblendvps", "avx_sse4xmm0", modifiers=[0x4A])
5978
5979# vpblendvb didn't have a 256-bit form until AVX2
5980add_group("avx2_sse4xmm0",
5981    cpu=["AVX2"],
5982    modifiers=["Op2Add"],
5983    vex=128,
5984    prefix=0x66,
5985    opcode=[0x0F, 0x3A, 0x00],
5986    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
5987              Operand(type="SIMDReg", size=128, dest="VEX"),
5988              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
5989              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
5990add_group("avx2_sse4xmm0",
5991    cpu=["AVX2"],
5992    modifiers=["Op2Add"],
5993    vex=256,
5994    prefix=0x66,
5995    opcode=[0x0F, 0x3A, 0x00],
5996    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
5997              Operand(type="SIMDReg", size=256, dest="VEX"),
5998              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
5999              Operand(type="SIMDReg", size=256, dest="VEXImmSrc")])
6000
6001add_insn("vpblendvb", "avx2_sse4xmm0", modifiers=[0x4C])
6002
6003for sfx, sz in zip("bwl", [8, 16, 32]):
6004    add_group("crc32",
6005        suffix=sfx,
6006        cpu=["SSE42"],
6007        opersize=sz,
6008        prefix=0xF2,
6009        opcode=[0x0F, 0x38, 0xF0+(sz!=8)],
6010        operands=[Operand(type="Reg", size=32, dest="Spare"),
6011                  Operand(type="RM", size=sz, relaxed=(sz==32), dest="EA")])
6012for sfx, sz in zip("bq", [8, 64]):
6013    add_group("crc32",
6014        suffix=sfx,
6015        cpu=["SSE42"],
6016        opersize=64,
6017        prefix=0xF2,
6018        opcode=[0x0F, 0x38, 0xF0+(sz!=8)],
6019        operands=[Operand(type="Reg", size=64, dest="Spare"),
6020                  Operand(type="RM", size=sz, relaxed=(sz==64), dest="EA")])
6021
6022add_insn("crc32", "crc32")
6023
6024add_group("extractps",
6025    cpu=["SSE41"],
6026    modifiers=["SetVEX"],
6027    prefix=0x66,
6028    opcode=[0x0F, 0x3A, 0x17],
6029    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
6030              Operand(type="SIMDReg", size=128, dest="Spare"),
6031              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6032add_group("extractps",
6033    cpu=["SSE41"],
6034    modifiers=["SetVEX"],
6035    opersize=64,
6036    prefix=0x66,
6037    opcode=[0x0F, 0x3A, 0x17],
6038    operands=[Operand(type="Reg", size=64, dest="EA"),
6039              Operand(type="SIMDReg", size=128, dest="Spare"),
6040              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6041
6042add_insn("extractps", "extractps")
6043add_insn("vextractps", "extractps", modifiers=[VEXL0], avx=True)
6044
6045add_group("insertps",
6046    cpu=["SSE41"],
6047    modifiers=["SetVEX"],
6048    prefix=0x66,
6049    opcode=[0x0F, 0x3A, 0x21],
6050    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6051              Operand(type="Mem", size=32, relaxed=True, dest="EA"),
6052              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6053add_group("insertps",
6054    cpu=["SSE41"],
6055    modifiers=["SetVEX"],
6056    prefix=0x66,
6057    opcode=[0x0F, 0x3A, 0x21],
6058    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6059              Operand(type="SIMDReg", size=128, dest="EA"),
6060              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6061add_group("insertps",
6062    cpu=["AVX"],
6063    vex=128,
6064    prefix=0x66,
6065    opcode=[0x0F, 0x3A, 0x21],
6066    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6067              Operand(type="SIMDReg", size=128, dest="VEX"),
6068              Operand(type="Mem", size=32, relaxed=True, dest="EA"),
6069              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6070add_group("insertps",
6071    cpu=["AVX"],
6072    vex=128,
6073    prefix=0x66,
6074    opcode=[0x0F, 0x3A, 0x21],
6075    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6076              Operand(type="SIMDReg", size=128, dest="VEX"),
6077              Operand(type="SIMDReg", size=128, dest="EA"),
6078              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6079
6080add_insn("insertps", "insertps")
6081add_insn("vinsertps", "insertps", modifiers=[VEXL0], avx=True)
6082
6083add_group("movntdqa",
6084    cpu=["SSE41"],
6085    modifiers=["SetVEX"],
6086    prefix=0x66,
6087    opcode=[0x0F, 0x38, 0x2A],
6088    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6089              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
6090add_group("movntdqa",
6091    cpu=["AVX2"],
6092    vex=256,
6093    prefix=0x66,
6094    opcode=[0x0F, 0x38, 0x2A],
6095    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6096              Operand(type="Mem", size=256, relaxed=True, dest="EA")])
6097
6098add_insn("movntdqa", "movntdqa")
6099add_insn("vmovntdqa", "movntdqa", modifiers=[VEXL0], avx=True)
6100
6101add_group("sse4pcmpstr",
6102    cpu=["SSE42"],
6103    modifiers=["Op2Add", "SetVEX"],
6104    prefix=0x66,
6105    opcode=[0x0F, 0x3A, 0x00],
6106    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6107              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6108              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6109
6110add_insn("pcmpestri", "sse4pcmpstr", modifiers=[0x61])
6111add_insn("pcmpestrm", "sse4pcmpstr", modifiers=[0x60])
6112add_insn("pcmpistri", "sse4pcmpstr", modifiers=[0x63])
6113add_insn("pcmpistrm", "sse4pcmpstr", modifiers=[0x62])
6114
6115add_insn("vpcmpestri", "sse4pcmpstr", modifiers=[0x61, VEXL0], avx=True)
6116add_insn("vpcmpestrm", "sse4pcmpstr", modifiers=[0x60, VEXL0], avx=True)
6117add_insn("vpcmpistri", "sse4pcmpstr", modifiers=[0x63, VEXL0], avx=True)
6118add_insn("vpcmpistrm", "sse4pcmpstr", modifiers=[0x62, VEXL0], avx=True)
6119
6120add_group("pextrb",
6121    cpu=["SSE41"],
6122    modifiers=["SetVEX"],
6123    prefix=0x66,
6124    opcode=[0x0F, 0x3A, 0x14],
6125    operands=[Operand(type="Mem", size=8, relaxed=True, dest="EA"),
6126              Operand(type="SIMDReg", size=128, dest="Spare"),
6127              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6128add_group("pextrb",
6129    cpu=["SSE41"],
6130    modifiers=["SetVEX"],
6131    prefix=0x66,
6132    opcode=[0x0F, 0x3A, 0x14],
6133    operands=[Operand(type="Reg", size=32, dest="EA"),
6134              Operand(type="SIMDReg", size=128, dest="Spare"),
6135              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6136add_group("pextrb",
6137    cpu=["SSE41"],
6138    modifiers=["SetVEX"],
6139    opersize=64,
6140    prefix=0x66,
6141    opcode=[0x0F, 0x3A, 0x14],
6142    operands=[Operand(type="Reg", size=64, dest="EA"),
6143              Operand(type="SIMDReg", size=128, dest="Spare"),
6144              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6145
6146add_insn("pextrb", "pextrb")
6147add_insn("vpextrb", "pextrb", modifiers=[VEXL0], avx=True)
6148
6149add_group("pextrd",
6150    cpu=["SSE41"],
6151    modifiers=["SetVEX"],
6152    prefix=0x66,
6153    opcode=[0x0F, 0x3A, 0x16],
6154    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
6155              Operand(type="SIMDReg", size=128, dest="Spare"),
6156              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6157
6158add_insn("pextrd", "pextrd")
6159add_insn("vpextrd", "pextrd", modifiers=[VEXL0], avx=True)
6160
6161add_group("pextrq",
6162    cpu=["SSE41"],
6163    modifiers=["SetVEX"],
6164    opersize=64,
6165    prefix=0x66,
6166    opcode=[0x0F, 0x3A, 0x16],
6167    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
6168              Operand(type="SIMDReg", size=128, dest="Spare"),
6169              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6170
6171add_insn("pextrq", "pextrq")
6172add_insn("vpextrq", "pextrq", modifiers=[VEXL0], avx=True)
6173
6174add_group("pinsrb",
6175    cpu=["SSE41"],
6176    modifiers=["SetVEX"],
6177    prefix=0x66,
6178    opcode=[0x0F, 0x3A, 0x20],
6179    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6180              Operand(type="Mem", size=8, relaxed=True, dest="EA"),
6181              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6182add_group("pinsrb",
6183    cpu=["SSE41"],
6184    modifiers=["SetVEX"],
6185    prefix=0x66,
6186    opcode=[0x0F, 0x3A, 0x20],
6187    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6188              Operand(type="Reg", size=32, dest="EA"),
6189              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6190add_group("pinsrb",
6191    cpu=["AVX"],
6192    vex=128,
6193    prefix=0x66,
6194    opcode=[0x0F, 0x3A, 0x20],
6195    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6196              Operand(type="SIMDReg", size=128, dest="VEX"),
6197              Operand(type="Mem", size=8, relaxed=True, dest="EA"),
6198              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6199add_group("pinsrb",
6200    cpu=["AVX"],
6201    vex=128,
6202    prefix=0x66,
6203    opcode=[0x0F, 0x3A, 0x20],
6204    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6205              Operand(type="SIMDReg", size=128, dest="VEX"),
6206              Operand(type="Reg", size=32, dest="EA"),
6207              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6208
6209add_insn("pinsrb", "pinsrb")
6210add_insn("vpinsrb", "pinsrb", modifiers=[VEXL0], avx=True)
6211
6212add_group("pinsrd",
6213    cpu=["SSE41"],
6214    modifiers=["SetVEX"],
6215    prefix=0x66,
6216    opcode=[0x0F, 0x3A, 0x22],
6217    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6218              Operand(type="RM", size=32, relaxed=True, dest="EA"),
6219              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6220add_group("pinsrd",
6221    cpu=["AVX"],
6222    vex=128,
6223    prefix=0x66,
6224    opcode=[0x0F, 0x3A, 0x22],
6225    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6226              Operand(type="SIMDReg", size=128, dest="VEX"),
6227              Operand(type="RM", size=32, relaxed=True, dest="EA"),
6228              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6229
6230add_insn("pinsrd", "pinsrd")
6231add_insn("vpinsrd", "pinsrd", modifiers=[VEXL0], avx=True)
6232
6233add_group("pinsrq",
6234    cpu=["SSE41"],
6235    modifiers=["SetVEX"],
6236    opersize=64,
6237    prefix=0x66,
6238    opcode=[0x0F, 0x3A, 0x22],
6239    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6240              Operand(type="RM", size=64, relaxed=True, dest="EA"),
6241              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6242add_group("pinsrq",
6243    cpu=["AVX"],
6244    vex=128,
6245    opersize=64,
6246    prefix=0x66,
6247    opcode=[0x0F, 0x3A, 0x22],
6248    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
6249              Operand(type="SIMDReg", size=128, dest="VEX"),
6250              Operand(type="RM", size=64, relaxed=True, dest="EA"),
6251              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6252
6253add_insn("pinsrq", "pinsrq")
6254add_insn("vpinsrq", "pinsrq", modifiers=[VEXL0], avx=True)
6255
6256for sz in [16, 32, 64]:
6257    add_group("sse4m%d" % sz,
6258        cpu=["SSE41"],
6259        modifiers=["Op2Add", "SetVEX"],
6260        prefix=0x66,
6261        opcode=[0x0F, 0x38, 0x00],
6262        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6263                  Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
6264    add_group("sse4m%d" % sz,
6265        cpu=["SSE41"],
6266        modifiers=["Op2Add", "SetVEX"],
6267        prefix=0x66,
6268        opcode=[0x0F, 0x38, 0x00],
6269        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6270                  Operand(type="SIMDReg", size=128, dest="EA")])
6271    add_group("sse4m%d" % sz,
6272        cpu=["AVX2"],
6273        modifiers=["Op2Add"],
6274        vex=256,
6275        prefix=0x66,
6276        opcode=[0x0F, 0x38, 0x00],
6277        operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6278                  Operand(type="Mem", size=sz*2, relaxed=True, dest="EA")])
6279    add_group("sse4m%d" % sz,
6280        cpu=["AVX2"],
6281        modifiers=["Op2Add"],
6282        vex=256,
6283        prefix=0x66,
6284        opcode=[0x0F, 0x38, 0x00],
6285        operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6286                  Operand(type="SIMDReg", size=128, dest="EA")])
6287
6288add_insn("pmovsxbw", "sse4m64", modifiers=[0x20])
6289add_insn("pmovsxwd", "sse4m64", modifiers=[0x23])
6290add_insn("pmovsxdq", "sse4m64", modifiers=[0x25])
6291add_insn("pmovzxbw", "sse4m64", modifiers=[0x30])
6292add_insn("pmovzxwd", "sse4m64", modifiers=[0x33])
6293add_insn("pmovzxdq", "sse4m64", modifiers=[0x35])
6294
6295add_insn("vpmovsxbw", "sse4m64", modifiers=[0x20, VEXL0], avx=True)
6296add_insn("vpmovsxwd", "sse4m64", modifiers=[0x23, VEXL0], avx=True)
6297add_insn("vpmovsxdq", "sse4m64", modifiers=[0x25, VEXL0], avx=True)
6298add_insn("vpmovzxbw", "sse4m64", modifiers=[0x30, VEXL0], avx=True)
6299add_insn("vpmovzxwd", "sse4m64", modifiers=[0x33, VEXL0], avx=True)
6300add_insn("vpmovzxdq", "sse4m64", modifiers=[0x35, VEXL0], avx=True)
6301
6302add_insn("pmovsxbd", "sse4m32", modifiers=[0x21])
6303add_insn("pmovsxwq", "sse4m32", modifiers=[0x24])
6304add_insn("pmovzxbd", "sse4m32", modifiers=[0x31])
6305add_insn("pmovzxwq", "sse4m32", modifiers=[0x34])
6306
6307add_insn("vpmovsxbd", "sse4m32", modifiers=[0x21, VEXL0], avx=True)
6308add_insn("vpmovsxwq", "sse4m32", modifiers=[0x24, VEXL0], avx=True)
6309add_insn("vpmovzxbd", "sse4m32", modifiers=[0x31, VEXL0], avx=True)
6310add_insn("vpmovzxwq", "sse4m32", modifiers=[0x34, VEXL0], avx=True)
6311
6312add_insn("pmovsxbq", "sse4m16", modifiers=[0x22])
6313add_insn("pmovzxbq", "sse4m16", modifiers=[0x32])
6314
6315add_insn("vpmovsxbq", "sse4m16", modifiers=[0x22, VEXL0], avx=True)
6316add_insn("vpmovzxbq", "sse4m16", modifiers=[0x32, VEXL0], avx=True)
6317
6318for sfx, sz in zip("wlq", [16, 32, 64]):
6319    add_group("cnt",
6320        suffix=sfx,
6321        modifiers=["Op1Add"],
6322        opersize=sz,
6323        prefix=0xF3,
6324        opcode=[0x0F, 0x00],
6325        operands=[Operand(type="Reg", size=sz, dest="Spare"),
6326                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
6327
6328add_insn("popcnt", "cnt", modifiers=[0xB8], cpu=["SSE42"])
6329
6330#####################################################################
6331# Intel AVX instructions
6332#####################################################################
6333
6334# Most AVX instructions are mixed in with above SSEx groups.
6335# Some make more sense to have separate groups due to naming conflicts
6336# that the v-named versions don't have to deal with.
6337add_group("vmovd",
6338    cpu=["AVX"],
6339    vex=128,
6340    prefix=0x66,
6341    opcode=[0x0F, 0x6E],
6342    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6343              Operand(type="RM", size=32, relaxed=True, dest="EA")])
6344add_group("vmovd",
6345    cpu=["AVX"],
6346    vex=128,
6347    prefix=0x66,
6348    opcode=[0x0F, 0x7E],
6349    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
6350              Operand(type="SIMDReg", size=128, dest="Spare")])
6351
6352add_insn("vmovd", "vmovd")
6353
6354add_group("vmovq",
6355    cpu=["AVX"],
6356    vex=128,
6357    prefix=0xF3,
6358    opcode=[0x0F, 0x7E],
6359    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6360              Operand(type="SIMDReg", size=128, dest="EA")])
6361add_group("vmovq",
6362    cpu=["AVX"],
6363    vex=128,
6364    prefix=0xF3,
6365    opcode=[0x0F, 0x7E],
6366    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6367              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
6368add_group("vmovq",
6369    cpu=["AVX"],
6370    vex=128,
6371    prefix=0x66,
6372    opcode=[0x0F, 0xD6],
6373    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
6374              Operand(type="SIMDReg", size=128, dest="Spare")])
6375add_group("vmovq",
6376    cpu=["AVX"],
6377    vex=128,
6378    opersize=64,
6379    prefix=0x66,
6380    opcode=[0x0F, 0x6E],
6381    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6382              Operand(type="RM", size=64, relaxed=True, dest="EA")])
6383add_group("vmovq",
6384    cpu=["AVX"],
6385    vex=128,
6386    opersize=64,
6387    prefix=0x66,
6388    opcode=[0x0F, 0x7E],
6389    operands=[Operand(type="RM", size=64, relaxed=True, dest="EA"),
6390              Operand(type="SIMDReg", size=128, dest="Spare")])
6391
6392add_insn("vmovq", "vmovq")
6393
6394# Some AVX variants don't add third operand
6395add_group("avx_xmm_xmm128",
6396    cpu=["AVX"],
6397    modifiers=["PreAdd", "Op1Add"],
6398    vex=128,
6399    prefix=0x00,
6400    opcode=[0x0F, 0x00],
6401    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6402              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6403add_group("avx_xmm_xmm128",
6404    cpu=["AVX"],
6405    modifiers=["PreAdd", "Op1Add"],
6406    vex=256,
6407    prefix=0x00,
6408    opcode=[0x0F, 0x00],
6409    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6410              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6411
6412add_insn("vmovshdup", "avx_xmm_xmm128", modifiers=[0xF3, 0x16])
6413add_insn("vmovsldup", "avx_xmm_xmm128", modifiers=[0xF3, 0x12])
6414add_insn("vrcpps",    "avx_xmm_xmm128", modifiers=[0, 0x53])
6415add_insn("vrsqrtps",  "avx_xmm_xmm128", modifiers=[0, 0x52])
6416add_insn("vsqrtps",   "avx_xmm_xmm128", modifiers=[0, 0x51])
6417add_insn("vsqrtpd",   "avx_xmm_xmm128", modifiers=[0x66, 0x51])
6418add_insn("vcvtdq2ps", "avx_xmm_xmm128", modifiers=[0, 0x5B])
6419add_insn("vcvtps2dq", "avx_xmm_xmm128", modifiers=[0x66, 0x5B])
6420add_insn("vcvttps2dq", "avx_xmm_xmm128", modifiers=[0xF3, 0x5B])
6421
6422add_group("avx_sse4imm",
6423    cpu=["SSE41"],
6424    modifiers=["Op2Add"],
6425    vex=128,
6426    prefix=0x66,
6427    opcode=[0x0F, 0x3A, 0x00],
6428    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6429              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6430              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6431add_group("avx_sse4imm",
6432    cpu=["AVX"],
6433    modifiers=["Op2Add"],
6434    vex=128,
6435    prefix=0x66,
6436    opcode=[0x0F, 0x3A, 0x00],
6437    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6438              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6439              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6440add_group("avx_sse4imm",
6441    cpu=["AVX"],
6442    modifiers=["Op2Add"],
6443    vex=256,
6444    prefix=0x66,
6445    opcode=[0x0F, 0x3A, 0x00],
6446    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6447              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6448              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6449
6450add_insn("vroundpd", "avx_sse4imm", modifiers=[0x09])
6451add_insn("vroundps", "avx_sse4imm", modifiers=[0x08])
6452
6453add_group("vmovddup",
6454    cpu=["AVX"],
6455    modifiers=["PreAdd", "Op1Add"],
6456    vex=128,
6457    prefix=0x00,
6458    opcode=[0x0F, 0x00],
6459    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6460              Operand(type="SIMDReg", size=128, dest="EA")])
6461add_group("vmovddup",
6462    cpu=["AVX"],
6463    modifiers=["PreAdd", "Op1Add"],
6464    vex=128,
6465    prefix=0x00,
6466    opcode=[0x0F, 0x00],
6467    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6468              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
6469add_group("vmovddup",
6470    cpu=["AVX"],
6471    modifiers=["PreAdd", "Op1Add"],
6472    vex=256,
6473    prefix=0x00,
6474    opcode=[0x0F, 0x00],
6475    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6476              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6477
6478add_insn("vmovddup",  "vmovddup", modifiers=[0xF2, 0x12])
6479
6480# Some xmm_xmm64 combinations only take two operands in AVX
6481# (VEX.vvvv must be 1111b)
6482add_group("avx_xmm_xmm64",
6483    cpu=["SSE2"],
6484    modifiers=["PreAdd", "Op1Add"],
6485    vex=128,
6486    prefix=0x00,
6487    opcode=[0x0F, 0x00],
6488    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6489              Operand(type="SIMDReg", size=128, dest="EA")])
6490add_group("avx_xmm_xmm64",
6491    cpu=["SSE2"],
6492    modifiers=["PreAdd", "Op1Add"],
6493    vex=128,
6494    prefix=0x00,
6495    opcode=[0x0F, 0x00],
6496    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6497              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
6498
6499add_insn("vcomisd",  "avx_xmm_xmm64", modifiers=[0x66, 0x2F], avx=True)
6500add_insn("vucomisd", "avx_xmm_xmm64", modifiers=[0x66, 0x2E], avx=True)
6501
6502# Some xmm_xmm64 combinations only take two operands in AVX
6503# (VEX.vvvv must be 1111b)
6504add_group("avx_xmm_xmm32",
6505    cpu=["SSE"],
6506    modifiers=["PreAdd", "Op1Add"],
6507    vex=128,
6508    prefix=0x00,
6509    opcode=[0x0F, 0x00],
6510    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6511              Operand(type="SIMDReg", size=128, dest="EA")])
6512add_group("avx_xmm_xmm32",
6513    cpu=["SSE"],
6514    modifiers=["PreAdd", "Op1Add"],
6515    vex=128,
6516    prefix=0x00,
6517    opcode=[0x0F, 0x00],
6518    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6519              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
6520
6521add_insn("vcomiss",  "avx_xmm_xmm32", modifiers=[0, 0x2F], avx=True)
6522add_insn("vucomiss", "avx_xmm_xmm32", modifiers=[0, 0x2E], avx=True)
6523
6524# Some conversion functions take ymm, xmm combination
6525add_group("avx_cvt_xmm64",
6526    cpu=["AVX"],
6527    modifiers=["PreAdd", "Op1Add"],
6528    vex=128,
6529    prefix=0x00,
6530    opcode=[0x0F, 0x00],
6531    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6532              Operand(type="SIMDReg", size=128, dest="EA")])
6533add_group("avx_cvt_xmm64",
6534    cpu=["AVX"],
6535    modifiers=["PreAdd", "Op1Add"],
6536    vex=128,
6537    prefix=0x00,
6538    opcode=[0x0F, 0x00],
6539    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6540              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
6541add_group("avx_cvt_xmm64",
6542    cpu=["AVX"],
6543    modifiers=["PreAdd", "Op1Add"],
6544    vex=256,
6545    prefix=0x00,
6546    opcode=[0x0F, 0x00],
6547    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6548              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6549
6550add_insn("vcvtdq2pd", "avx_cvt_xmm64", modifiers=[0xF3, 0xE6])
6551add_insn("vcvtps2pd", "avx_cvt_xmm64", modifiers=[0, 0x5A])
6552
6553# Some SSE3 opcodes are only two operand in AVX
6554# (VEX.vvvv must be 1111b)
6555add_group("avx_ssse3_2op",
6556    cpu=["AVX"],
6557    modifiers=["Op2Add"],
6558    vex=128,
6559    prefix=0x66,
6560    opcode=[0x0F, 0x38, 0x00],
6561    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6562              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6563add_insn("vphminposuw", "avx_ssse3_2op", modifiers=[0x41], avx=True)
6564
6565# VPABS* are extended to 256-bit in AVX2
6566for cpu, sz in zip(["AVX", "AVX2"], [128, 256]):
6567    add_group("avx2_ssse3_2op",
6568        cpu=[cpu],
6569        modifiers=["Op2Add"],
6570        vex=sz,
6571        prefix=0x66,
6572        opcode=[0x0F, 0x38, 0x00],
6573        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6574                  Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA")])
6575add_insn("vpabsb",     "avx2_ssse3_2op", modifiers=[0x1C], avx=True)
6576add_insn("vpabsw",     "avx2_ssse3_2op", modifiers=[0x1D], avx=True)
6577add_insn("vpabsd",     "avx2_ssse3_2op", modifiers=[0x1E], avx=True)
6578
6579# Some conversion functions take xmm, ymm combination
6580# Need separate x and y versions for gas mode
6581add_group("avx_cvt_xmm128_x",
6582    cpu=["AVX"],
6583    modifiers=["PreAdd", "Op1Add"],
6584    vex=128,
6585    prefix=0x00,
6586    opcode=[0x0F, 0x00],
6587    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6588              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6589add_group("avx_cvt_xmm128_y",
6590    cpu=["AVX"],
6591    modifiers=["PreAdd", "Op1Add"],
6592    vex=256,
6593    prefix=0x00,
6594    opcode=[0x0F, 0x00],
6595    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6596              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6597
6598add_group("avx_cvt_xmm128",
6599    cpu=["AVX"],
6600    modifiers=["PreAdd", "Op1Add"],
6601    vex=128,
6602    prefix=0x00,
6603    opcode=[0x0F, 0x00],
6604    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6605              Operand(type="SIMDRM", size=128, dest="EA")])
6606add_group("avx_cvt_xmm128",
6607    cpu=["AVX"],
6608    modifiers=["PreAdd", "Op1Add"],
6609    vex=256,
6610    prefix=0x00,
6611    opcode=[0x0F, 0x00],
6612    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6613              Operand(type="SIMDRM", size=256, dest="EA")])
6614
6615add_insn("vcvtpd2dqx", "avx_cvt_xmm128_x", modifiers=[0xF2, 0xE6], parser="gas")
6616add_insn("vcvtpd2dqy", "avx_cvt_xmm128_y", modifiers=[0xF2, 0xE6], parser="gas")
6617add_insn("vcvtpd2dq", "avx_cvt_xmm128", modifiers=[0xF2, 0xE6])
6618
6619add_insn("vcvtpd2psx", "avx_cvt_xmm128_x", modifiers=[0x66, 0x5A], parser="gas")
6620add_insn("vcvtpd2psy", "avx_cvt_xmm128_y", modifiers=[0x66, 0x5A], parser="gas")
6621add_insn("vcvtpd2ps", "avx_cvt_xmm128", modifiers=[0x66, 0x5A])
6622
6623add_insn("vcvttpd2dqx", "avx_cvt_xmm128_x", modifiers=[0x66, 0xE6], parser="gas")
6624add_insn("vcvttpd2dqy", "avx_cvt_xmm128_y", modifiers=[0x66, 0xE6], parser="gas")
6625add_insn("vcvttpd2dq", "avx_cvt_xmm128", modifiers=[0x66, 0xE6])
6626
6627# Instructions new to AVX
6628add_insn("vtestps", "sse4", modifiers=[0x0E, VEXL0], avx=True)
6629add_insn("vtestpd", "sse4", modifiers=[0x0F, VEXL0], avx=True)
6630
6631add_group("vbroadcastss",
6632    cpu=["AVX"],
6633    vex=128,
6634    prefix=0x66,
6635    opcode=[0x0F, 0x38, 0x18],
6636    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6637              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
6638add_group("vbroadcastss",
6639    cpu=["AVX"],
6640    vex=256,
6641    prefix=0x66,
6642    opcode=[0x0F, 0x38, 0x18],
6643    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6644              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
6645add_group("vbroadcastss",
6646    cpu=["AVX2"],
6647    vex=128,
6648    prefix=0x66,
6649    opcode=[0x0F, 0x38, 0x18],
6650    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6651              Operand(type="SIMDReg", size=128, dest="EA")])
6652add_group("vbroadcastss",
6653    cpu=["AVX2"],
6654    vex=256,
6655    prefix=0x66,
6656    opcode=[0x0F, 0x38, 0x18],
6657    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6658              Operand(type="SIMDReg", size=128, dest="EA")])
6659
6660add_insn("vbroadcastss", "vbroadcastss")
6661
6662add_group("vbroadcastsd",
6663    cpu=["AVX"],
6664    vex=256,
6665    prefix=0x66,
6666    opcode=[0x0F, 0x38, 0x19],
6667    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6668              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
6669add_group("vbroadcastsd",
6670    cpu=["AVX2"],
6671    vex=256,
6672    prefix=0x66,
6673    opcode=[0x0F, 0x38, 0x19],
6674    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6675              Operand(type="SIMDReg", size=128, dest="EA")])
6676
6677add_insn("vbroadcastsd", "vbroadcastsd")
6678
6679add_group("vbroadcastif128",
6680    modifiers=["Op2Add"],
6681    vex=256,
6682    prefix=0x66,
6683    opcode=[0x0F, 0x38, 0x00],
6684    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6685              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
6686
6687add_insn("vbroadcastf128", "vbroadcastif128", modifiers=[0x1A], cpu=["AVX"])
6688add_insn("vbroadcasti128", "vbroadcastif128", modifiers=[0x5A], cpu=["AVX2"])
6689
6690add_group("vextractif128",
6691    modifiers=["Op2Add"],
6692    vex=256,
6693    prefix=0x66,
6694    opcode=[0x0F, 0x3A, 0x00],
6695    operands=[Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6696              Operand(type="SIMDReg", size=256, dest="Spare"),
6697              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6698
6699add_insn("vextractf128", "vextractif128", modifiers=[0x19], cpu=["AVX"])
6700add_insn("vextracti128", "vextractif128", modifiers=[0x39], cpu=["AVX2"])
6701
6702add_group("vinsertif128",
6703    modifiers=["Op2Add"],
6704    vex=256,
6705    prefix=0x66,
6706    opcode=[0x0F, 0x3A, 0x00],
6707    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6708              Operand(type="SIMDReg", size=256, dest="VEX"),
6709              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6710              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6711
6712add_insn("vinsertf128", "vinsertif128", modifiers=[0x18], cpu=["AVX"])
6713add_insn("vinserti128", "vinsertif128", modifiers=[0x38], cpu=["AVX2"])
6714
6715add_group("vzero",
6716    cpu=["AVX"],
6717    modifiers=["SetVEX"],
6718    opcode=[0x0F, 0x77],
6719    operands=[])
6720
6721add_insn("vzeroall", "vzero", modifiers=[VEXL1])
6722add_insn("vzeroupper", "vzero", modifiers=[VEXL0])
6723
6724add_group("vmaskmov",
6725    modifiers=["Op2Add"],
6726    vex=128,
6727    prefix=0x66,
6728    opcode=[0x0F, 0x38, 0x00],
6729    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6730              Operand(type="SIMDReg", size=128, dest="VEX"),
6731              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6732add_group("vmaskmov",
6733    modifiers=["Op2Add"],
6734    vex=256,
6735    prefix=0x66,
6736    opcode=[0x0F, 0x38, 0x00],
6737    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6738              Operand(type="SIMDReg", size=256, dest="VEX"),
6739              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6740add_group("vmaskmov",
6741    modifiers=["Op2Add"],
6742    vex=128,
6743    prefix=0x66,
6744    opcode=[0x0F, 0x38, 0x02],
6745    operands=[Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6746              Operand(type="SIMDReg", size=128, dest="VEX"),
6747              Operand(type="SIMDReg", size=128, dest="Spare")])
6748add_group("vmaskmov",
6749    modifiers=["Op2Add"],
6750    vex=256,
6751    prefix=0x66,
6752    opcode=[0x0F, 0x38, 0x02],
6753    operands=[Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6754              Operand(type="SIMDReg", size=256, dest="VEX"),
6755              Operand(type="SIMDReg", size=256, dest="Spare")])
6756
6757add_insn("vmaskmovps", "vmaskmov", modifiers=[0x2C], cpu=["AVX"])
6758add_insn("vmaskmovpd", "vmaskmov", modifiers=[0x2D], cpu=["AVX"])
6759
6760add_group("vpermil",
6761    cpu=["AVX"],
6762    modifiers=["Op2Add"],
6763    vex=128,
6764    prefix=0x66,
6765    opcode=[0x0F, 0x38, 0x08],
6766    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6767              Operand(type="SIMDReg", size=128, dest="VEX"),
6768              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
6769add_group("vpermil",
6770    cpu=["AVX"],
6771    modifiers=["Op2Add"],
6772    vex=256,
6773    prefix=0x66,
6774    opcode=[0x0F, 0x38, 0x08],
6775    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6776              Operand(type="SIMDReg", size=256, dest="VEX"),
6777              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6778add_group("vpermil",
6779    cpu=["AVX"],
6780    modifiers=["Op2Add"],
6781    vex=128,
6782    prefix=0x66,
6783    opcode=[0x0F, 0x3A, 0x00],
6784    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
6785              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
6786              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6787add_group("vpermil",
6788    cpu=["AVX"],
6789    modifiers=["Op2Add"],
6790    vex=256,
6791    prefix=0x66,
6792    opcode=[0x0F, 0x3A, 0x00],
6793    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6794              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6795              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6796
6797add_insn("vpermilpd", "vpermil", modifiers=[0x05])
6798add_insn("vpermilps", "vpermil", modifiers=[0x04])
6799
6800add_group("vperm2f128",
6801    cpu=["AVX"],
6802    vex=256,
6803    prefix=0x66,
6804    opcode=[0x0F, 0x3A, 0x06],
6805    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6806              Operand(type="SIMDReg", size=256, dest="VEX"),
6807              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6808              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6809
6810add_insn("vperm2f128", "vperm2f128")
6811
6812#####################################################################
6813# Intel AVX2 instructions
6814#####################################################################
6815
6816# Most AVX2 instructions are mixed in with above SSEx/AVX groups.
6817# Some make more sense to have separate groups.
6818
6819# vex.vvvv=1111b
6820add_group("vperm_var_avx2",
6821    cpu=["AVX2"],
6822    modifiers=["Op2Add"],
6823    vex=256,
6824    vexw=0,
6825    prefix=0x66,
6826    opcode=[0x0F, 0x38, 0x00],
6827    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6828              Operand(type="SIMDReg", size=256, dest="VEX"),
6829              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
6830
6831add_insn("vpermd",     "vperm_var_avx2", modifiers=[0x36])
6832add_insn("vpermps",    "vperm_var_avx2", modifiers=[0x16])
6833
6834# vex.vvvv=1111b
6835add_group("vperm_imm_avx2",
6836    cpu=["AVX2"],
6837    modifiers=["Op2Add"],
6838    vex=256,
6839    vexw=1,
6840    prefix=0x66,
6841    opcode=[0x0F, 0x3A, 0x00],
6842    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6843              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6844              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6845
6846add_insn("vpermq",     "vperm_imm_avx2", modifiers=[0x00])
6847add_insn("vpermpd",    "vperm_imm_avx2", modifiers=[0x01])
6848
6849add_group("vperm2i128_avx2",
6850    cpu=["AVX2"],
6851    vex=256,
6852    prefix=0x66,
6853    opcode=[0x0F, 0x3A, 0x46],
6854    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
6855              Operand(type="SIMDReg", size=256, dest="VEX"),
6856              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
6857              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
6858
6859add_insn("vperm2i128", "vperm2i128_avx2")
6860
6861# vex.vvvv=1111b
6862for sz in [128, 256]:
6863    add_group("vpbroadcastb_avx2",
6864        cpu=["AVX2"],
6865        vex=sz,
6866        vexw=0,
6867        prefix=0x66,
6868        opcode=[0x0F, 0x38, 0x78],
6869        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6870                  Operand(type="SIMDReg", size=128, relaxed=True, dest="EA")])
6871# vex.vvvv=1111b
6872for sz in [128, 256]:
6873    add_group("vpbroadcastb_avx2",
6874        cpu=["AVX2"],
6875        vex=sz,
6876        vexw=0,
6877        prefix=0x66,
6878        opcode=[0x0F, 0x38, 0x78],
6879        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6880                  Operand(type="RM", size=8, relaxed=True, dest="EA")])
6881
6882add_insn("vpbroadcastb", "vpbroadcastb_avx2")
6883
6884# vex.vvvv=1111b
6885for sz in [128, 256]:
6886    add_group("vpbroadcastw_avx2",
6887        cpu=["AVX2"],
6888        vex=sz,
6889        vexw=0,
6890        prefix=0x66,
6891        opcode=[0x0F, 0x38, 0x79],
6892        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6893                  Operand(type="SIMDReg", size=128, relaxed=True, dest="EA")])
6894# vex.vvvv=1111b
6895for sz in [128, 256]:
6896    add_group("vpbroadcastw_avx2",
6897        cpu=["AVX2"],
6898        vex=sz,
6899        vexw=0,
6900        prefix=0x66,
6901        opcode=[0x0F, 0x38, 0x79],
6902        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6903                  Operand(type="RM", size=16, relaxed=True, dest="EA")])
6904
6905add_insn("vpbroadcastw", "vpbroadcastw_avx2")
6906
6907# vex.vvvv=1111b
6908for sz in [128, 256]:
6909    add_group("vpbroadcastd_avx2",
6910        cpu=["AVX2"],
6911        vex=sz,
6912        vexw=0,
6913        prefix=0x66,
6914        opcode=[0x0F, 0x38, 0x58],
6915        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6916                  Operand(type="SIMDReg", size=128, relaxed=True, dest="EA")])
6917# vex.vvvv=1111b
6918for sz in [128, 256]:
6919    add_group("vpbroadcastd_avx2",
6920        cpu=["AVX2"],
6921        vex=sz,
6922        vexw=0,
6923        prefix=0x66,
6924        opcode=[0x0F, 0x38, 0x58],
6925        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6926                  Operand(type="RM", size=32, relaxed=True, dest="EA")])
6927
6928add_insn("vpbroadcastd", "vpbroadcastd_avx2")
6929
6930# vex.vvvv=1111b
6931for sz in [128, 256]:
6932    add_group("vpbroadcastq_avx2",
6933        cpu=["AVX2"],
6934        vex=sz,
6935        vexw=0,
6936        prefix=0x66,
6937        opcode=[0x0F, 0x38, 0x59],
6938        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6939                  Operand(type="SIMDReg", size=128, relaxed=True, dest="EA")])
6940# vex.vvvv=1111b
6941for sz in [128, 256]:
6942    add_group("vpbroadcastq_avx2",
6943        cpu=["AVX2"],
6944        vex=sz,
6945        vexw=0,
6946        prefix=0x66,
6947        opcode=[0x0F, 0x38, 0x59],
6948        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6949                  Operand(type="RM", size=64, relaxed=True, dest="EA")])
6950
6951add_insn("vpbroadcastq", "vpbroadcastq_avx2")
6952
6953for sz in [128, 256]:
6954    add_group("vpshiftv_vexw0_avx2",
6955        cpu=["AVX2"],
6956        modifiers=["Op2Add"],
6957        vex=sz,
6958        vexw=0,
6959        prefix=0x66,
6960        opcode=[0x0F, 0x38, 0x00],
6961        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6962                  Operand(type="SIMDReg", size=sz, dest="VEX"),
6963                  Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA")])
6964
6965for sz in [128, 256]:
6966    add_group("vpshiftv_vexw1_avx2",
6967        cpu=["AVX2"],
6968        modifiers=["Op2Add"],
6969        vex=sz,
6970        vexw=1,
6971        prefix=0x66,
6972        opcode=[0x0F, 0x38, 0x00],
6973        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6974                  Operand(type="SIMDReg", size=sz, dest="VEX"),
6975                  Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA")])
6976
6977add_insn("vpsrlvd", "vpshiftv_vexw0_avx2", modifiers=[0x45])
6978add_insn("vpsrlvq", "vpshiftv_vexw1_avx2", modifiers=[0x45])
6979add_insn("vpsravd", "vpshiftv_vexw0_avx2", modifiers=[0x46])
6980
6981add_insn("vpsllvd", "vpshiftv_vexw0_avx2", modifiers=[0x47])
6982add_insn("vpsllvq", "vpshiftv_vexw1_avx2", modifiers=[0x47])
6983
6984add_insn("vpmaskmovd", "vmaskmov", modifiers=[0x8C], cpu=["AVX2"])
6985
6986# vex.vvvv=1111b
6987for sz in [128, 256]:
6988    add_group("vmaskmov_vexw1_avx2",
6989        cpu=["AVX2"],
6990        modifiers=["Op2Add"],
6991        vex=sz,
6992        vexw=1,
6993        prefix=0x66,
6994        opcode=[0x0F, 0x38, 0x00],
6995        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
6996                  Operand(type="SIMDReg", size=sz, dest="VEX"),
6997                  Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA")])
6998
6999for sz in [128, 256]:
7000    add_group("vmaskmov_vexw1_avx2",
7001        cpu=["AVX2"],
7002        modifiers=["Op2Add"],
7003        vex=sz,
7004        vexw=1,
7005        prefix=0x66,
7006        opcode=[0x0F, 0x38, 0x02],
7007        operands=[Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA"),
7008                  Operand(type="SIMDReg", size=sz, dest="VEX"),
7009                  Operand(type="SIMDReg", size=sz, dest="Spare")])
7010
7011add_insn("vpmaskmovq", "vmaskmov_vexw1_avx2", modifiers=[0x8C])
7012
7013for sz in [128, 256]:
7014    add_group("vex_66_0F3A_imm8_avx2",
7015        cpu=["AVX2"],
7016        modifiers=["Op2Add"],
7017        vex=sz,
7018        vexw=0,
7019        prefix=0x66,
7020        opcode=[0x0F, 0x3A, 0x00],
7021        operands=[Operand(type="SIMDReg", size=sz, dest="Spare"),
7022                  Operand(type="SIMDReg", size=sz, dest="VEX"),
7023                  Operand(type="SIMDRM", size=sz, relaxed=True, dest="EA"),
7024                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7025
7026add_insn("vpblendd", "vex_66_0F3A_imm8_avx2", modifiers=[0x02])
7027
7028# Vector register in EA.
7029add_group("gather_64x_64x",
7030    cpu=["AVX2"],
7031    modifiers=["Op2Add"],
7032    vex=128,
7033    vexw=1,
7034    prefix=0x66,
7035    opcode=[0x0F, 0x38, 0x00],
7036    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7037              Operand(type="MemXMMIndex", size=64, relaxed=True, dest="EA"),
7038              Operand(type="SIMDReg", size=128, dest="VEX")])
7039add_group("gather_64x_64x",
7040    cpu=["AVX2"],
7041    modifiers=["Op2Add"],
7042    vex=256,
7043    vexw=1,
7044    prefix=0x66,
7045    opcode=[0x0F, 0x38, 0x00],
7046    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7047              Operand(type="MemXMMIndex", size=64, relaxed=True, dest="EA"),
7048              Operand(type="SIMDReg", size=256, dest="VEX")])
7049add_insn("vgatherdpd", "gather_64x_64x", modifiers=[0x92])
7050add_insn("vpgatherdq", "gather_64x_64x", modifiers=[0x90])
7051
7052add_group("gather_64x_64y",
7053    cpu=["AVX2"],
7054    modifiers=["Op2Add"],
7055    vex=128,
7056    vexw=1,
7057    prefix=0x66,
7058    opcode=[0x0F, 0x38, 0x00],
7059    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7060              Operand(type="MemXMMIndex", size=64, relaxed=True, dest="EA"),
7061              Operand(type="SIMDReg", size=128, dest="VEX")])
7062add_group("gather_64x_64y",
7063    cpu=["AVX2"],
7064    modifiers=["Op2Add"],
7065    vex=256,
7066    vexw=1,
7067    prefix=0x66,
7068    opcode=[0x0F, 0x38, 0x00],
7069    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7070              Operand(type="MemYMMIndex", size=64, relaxed=True, dest="EA"),
7071              Operand(type="SIMDReg", size=256, dest="VEX")])
7072add_insn("vgatherqpd", "gather_64x_64y", modifiers=[0x93])
7073add_insn("vpgatherqq", "gather_64x_64y", modifiers=[0x91])
7074
7075add_group("gather_32x_32y",
7076    cpu=["AVX2"],
7077    modifiers=["Op2Add"],
7078    vex=128,
7079    vexw=0,
7080    prefix=0x66,
7081    opcode=[0x0F, 0x38, 0x00],
7082    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7083              Operand(type="MemXMMIndex", size=32, relaxed=True, dest="EA"),
7084              Operand(type="SIMDReg", size=128, dest="VEX")])
7085add_group("gather_32x_32y",
7086    cpu=["AVX2"],
7087    modifiers=["Op2Add"],
7088    vex=256,
7089    vexw=0,
7090    prefix=0x66,
7091    opcode=[0x0F, 0x38, 0x00],
7092    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7093              Operand(type="MemYMMIndex", size=32, relaxed=True, dest="EA"),
7094              Operand(type="SIMDReg", size=256, dest="VEX")])
7095add_insn("vgatherdps", "gather_32x_32y", modifiers=[0x92])
7096add_insn("vpgatherdd", "gather_32x_32y", modifiers=[0x90])
7097
7098add_group("gather_32x_32y_128",
7099    cpu=["AVX2"],
7100    modifiers=["Op2Add"],
7101    vex=128,
7102    vexw=0,
7103    prefix=0x66,
7104    opcode=[0x0F, 0x38, 0x00],
7105    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7106              Operand(type="MemXMMIndex", size=32, relaxed=True, dest="EA"),
7107              Operand(type="SIMDReg", size=128, dest="VEX")])
7108add_group("gather_32x_32y_128",
7109    cpu=["AVX2"],
7110    modifiers=["Op2Add"],
7111    vex=256,
7112    vexw=0,
7113    prefix=0x66,
7114    opcode=[0x0F, 0x38, 0x00],
7115    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7116              Operand(type="MemYMMIndex", size=32, relaxed=True, dest="EA"),
7117              Operand(type="SIMDReg", size=128, dest="VEX")])
7118add_insn("vgatherqps", "gather_32x_32y_128", modifiers=[0x93])
7119add_insn("vpgatherqd", "gather_32x_32y_128", modifiers=[0x91])
7120
7121#####################################################################
7122# Intel FMA instructions
7123#####################################################################
7124
7125### 128/256b FMA PS
7126add_group("vfma_ps",
7127    cpu=["FMA"],
7128    modifiers=["Op2Add"],
7129    vex=128,
7130    vexw=0, # single precision
7131    prefix=0x66,
7132    opcode=[0x0F, 0x38, 0x00],
7133    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7134              Operand(type="SIMDReg", size=128, dest="VEX"),
7135              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7136add_group("vfma_ps",
7137    cpu=["FMA"],
7138    modifiers=["Op2Add"],
7139    vex=256,
7140    vexw=0, # single precision
7141    prefix=0x66,
7142    opcode=[0x0F, 0x38, 0x00],
7143    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7144              Operand(type="SIMDReg", size=256, dest="VEX"),
7145              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
7146
7147### 128/256b FMA PD(W=1)
7148add_group("vfma_pd",
7149    cpu=["FMA"],
7150    modifiers=["Op2Add"],
7151    vex=128,
7152    vexw=1, # double precision
7153    prefix=0x66,
7154    opcode=[0x0F, 0x38, 0x00],
7155    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7156              Operand(type="SIMDReg", size=128, dest="VEX"),
7157              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7158add_group("vfma_pd",
7159    cpu=["FMA"],
7160    modifiers=["Op2Add"],
7161    vex=256,
7162    vexw=1, # double precision
7163    prefix=0x66,
7164    opcode=[0x0F, 0x38, 0x00],
7165    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7166              Operand(type="SIMDReg", size=256, dest="VEX"),
7167              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
7168
7169add_group("vfma_ss",
7170    cpu=["FMA"],
7171    modifiers=["Op2Add"],
7172    vex=128,
7173    vexw=0,
7174    prefix=0x66,
7175    opcode=[0x0F, 0x38, 0x00],
7176    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7177              Operand(type="SIMDReg", size=128, dest="VEX"),
7178              Operand(type="SIMDReg", size=128, dest="EA")])
7179
7180add_group("vfma_ss",
7181    cpu=["FMA"],
7182    modifiers=["Op2Add"],
7183    vex=128,
7184    vexw=0,
7185    prefix=0x66,
7186    opcode=[0x0F, 0x38, 0x00],
7187    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7188              Operand(type="SIMDReg", size=128, dest="VEX"),
7189              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
7190
7191add_group("vfma_sd",
7192    cpu=["FMA"],
7193    modifiers=["Op2Add"],
7194    vex=128,
7195    vexw=1,
7196    prefix=0x66,
7197    opcode=[0x0F, 0x38, 0x00],
7198    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7199              Operand(type="SIMDReg", size=128, dest="VEX"),
7200              Operand(type="SIMDReg", size=128, dest="EA")])
7201
7202add_group("vfma_sd",
7203    cpu=["FMA"],
7204    modifiers=["Op2Add"],
7205    vex=128,
7206    vexw=1,
7207    prefix=0x66,
7208    opcode=[0x0F, 0x38, 0x00],
7209    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7210              Operand(type="SIMDReg", size=128, dest="VEX"),
7211              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
7212
7213for orderval, order in enumerate(["132", "213", "231"]):
7214    ov = orderval << 4
7215    for combval, comb in enumerate(["ps", "pd", "ss", "sd"]):
7216        cv = combval >> 1
7217        add_insn("vfmadd"+order+comb, "vfma_"+comb, modifiers=[0x98+ov+cv])
7218        add_insn("vfmsub"+order+comb, "vfma_"+comb, modifiers=[0x9A+ov+cv])
7219        add_insn("vfnmsub"+order+comb, "vfma_"+comb, modifiers=[0x9E+ov+cv])
7220        add_insn("vfnmadd"+order+comb, "vfma_"+comb, modifiers=[0x9C+ov+cv])
7221
7222    # no ss/sd for these
7223    for comb in ["ps", "pd"]:
7224        add_insn("vfmaddsub"+order+comb, "vfma_"+comb, modifiers=[0x96+ov])
7225        add_insn("vfmsubadd"+order+comb, "vfma_"+comb, modifiers=[0x97+ov])
7226
7227#####################################################################
7228# Intel AES instructions
7229#####################################################################
7230
7231add_group("aes",
7232    cpu=["AES"],
7233    modifiers=["Op1Add", "Op2Add", "SetVEX"],
7234    prefix=0x66,
7235    opcode=[0x0F, 0x00, 0x00],
7236    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
7237              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7238add_group("aes",
7239    cpu=["AES", "AVX"],
7240    modifiers=["Op1Add", "Op2Add"],
7241    vex=128,
7242    prefix=0x66,
7243    opcode=[0x0F, 0x00, 0x00],
7244    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7245              Operand(type="SIMDReg", size=128, dest="VEX"),
7246              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7247
7248
7249add_insn("aesenc", "aes", modifiers=[0x38, 0xDC])
7250add_insn("aesenclast", "aes", modifiers=[0x38, 0xDD])
7251add_insn("aesdec", "aes", modifiers=[0x38, 0xDE])
7252add_insn("aesdeclast", "aes", modifiers=[0x38, 0xDF])
7253
7254add_insn("vaesenc", "aes", modifiers=[0x38, 0xDC, VEXL0], avx=True)
7255add_insn("vaesenclast", "aes", modifiers=[0x38, 0xDD, VEXL0], avx=True)
7256add_insn("vaesdec", "aes", modifiers=[0x38, 0xDE, VEXL0], avx=True)
7257add_insn("vaesdeclast", "aes", modifiers=[0x38, 0xDF, VEXL0], avx=True)
7258
7259add_group("aesimc",
7260    cpu=["AES"],
7261    modifiers=["Op1Add", "Op2Add", "SetVEX"],
7262    prefix=0x66,
7263    opcode=[0x0F, 0x00, 0x00],
7264    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7265              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7266
7267add_insn("aesimc", "aesimc", modifiers=[0x38, 0xDB])
7268add_insn("vaesimc", "aesimc", modifiers=[0x38, 0xDB, VEXL0], avx=True)
7269
7270
7271add_group("aes_imm",
7272    cpu=["AES"],
7273    modifiers=["Op1Add", "Op2Add", "SetVEX"],
7274    prefix=0x66,
7275    opcode=[0x0F, 0x00, 0x00],
7276    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7277              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7278              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7279
7280add_insn("aeskeygenassist", "aes_imm", modifiers=[0x3A, 0xDF])
7281add_insn("vaeskeygenassist", "aes_imm", modifiers=[0x3A, 0xDF, VEXL0],
7282         avx=True)
7283
7284#####################################################################
7285# Intel PCLMULQDQ instruction
7286#####################################################################
7287
7288add_group("pclmulqdq",
7289    cpu=["CLMUL"],
7290    modifiers=["Op1Add", "Op2Add", "SetVEX"],
7291    prefix=0x66,
7292    opcode=[0x0F, 0x00, 0x00],
7293    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
7294              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7295              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7296add_group("pclmulqdq",
7297    cpu=["CLMUL", "AVX"],
7298    modifiers=["Op1Add", "Op2Add"],
7299    vex=128,
7300    prefix=0x66,
7301    opcode=[0x0F, 0x00, 0x00],
7302    operands=[Operand(type="SIMDReg", size=128,               dest="Spare"),
7303              Operand(type="SIMDReg", size=128,               dest="VEX"),
7304              Operand(type="SIMDRM",  size=128, relaxed=True, dest="EA"),
7305              Operand(type="Imm",     size=8,   relaxed=True, dest="Imm")])
7306
7307add_insn("pclmulqdq", "pclmulqdq", modifiers=[0x3A, 0x44])
7308add_insn("vpclmulqdq", "pclmulqdq", modifiers=[0x3A, 0x44, VEXL0], avx=True)
7309
7310add_group("pclmulqdq_fixed",
7311    cpu=["CLMUL"],
7312    modifiers=["Imm8", "SetVEX"],
7313    prefix=0x66,
7314    opcode=[0x0F, 0x3A, 0x44],
7315    operands=[Operand(type="SIMDReg", size=128, dest="SpareVEX"),
7316              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7317add_group("pclmulqdq_fixed",
7318    cpu=["CLMUL", "AVX"],
7319    modifiers=["Imm8"],
7320    vex=128,
7321    prefix=0x66,
7322    opcode=[0x0F, 0x3A, 0x44],
7323    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7324              Operand(type="SIMDReg", size=128, dest="VEX"),
7325              Operand(type="SIMDRM",  size=128, relaxed=True, dest="EA")])
7326
7327for comb, combval in zip(["lql","hql","lqh","hqh"], [0x00,0x01,0x10,0x11]):
7328    add_insn("pclmul"+comb+"qdq", "pclmulqdq_fixed", modifiers=[combval])
7329    add_insn("vpclmul"+comb+"qdq", "pclmulqdq_fixed",
7330             modifiers=[combval, VEXL0], avx=True)
7331
7332#####################################################################
7333# AVX Post-32nm instructions
7334#####################################################################
7335
7336# RDRAND
7337add_group("rdrand",
7338    cpu=["RDRAND"],
7339    opersize=16,
7340    opcode=[0x0F, 0xC7],
7341    spare=6,
7342    operands=[Operand(type="Reg", size=16, dest="EA")])
7343add_group("rdrand",
7344    #suffix="l",
7345    cpu=["RDRAND"],
7346    opersize=32,
7347    opcode=[0x0F, 0xC7],
7348    spare=6,
7349    operands=[Operand(type="Reg", size=32, dest="EA")])
7350add_group("rdrand",
7351    cpu=["RDRAND"],
7352    opersize=64,
7353    opcode=[0x0F, 0xC7],
7354    spare=6,
7355    operands=[Operand(type="Reg", size=64, dest="EA")])
7356add_insn("rdrand", "rdrand")
7357
7358# FSGSBASE instructions
7359add_group("fs_gs_base",
7360    only64=True,
7361    cpu=["FSGSBASE"],
7362    modifiers=['SpAdd'],
7363    opersize=32,
7364    prefix=0xF3,
7365    opcode=[0x0F, 0xAE],
7366    operands=[Operand(type="Reg", size=32, dest="EA")])
7367add_group("fs_gs_base",
7368    only64=True,
7369    cpu=["FSGSBASE"],
7370    opersize=64,
7371    modifiers=['SpAdd'],
7372    prefix=0xF3,
7373    opcode=[0x0F, 0xAE],
7374    operands=[Operand(type="Reg", size=64, dest="EA")])
7375
7376add_insn("rdfsbase", "fs_gs_base", modifiers=[0], only64=True)
7377add_insn("rdgsbase", "fs_gs_base", modifiers=[1], only64=True)
7378add_insn("wrfsbase", "fs_gs_base", modifiers=[2], only64=True)
7379add_insn("wrgsbase", "fs_gs_base", modifiers=[3], only64=True)
7380
7381# Float-16 conversion instructions
7382for g in ['ps2ph', 'ph2ps']:
7383    operands1=[]
7384    operands1.append(Operand(type="SIMDReg", size=128, dest="EA"))
7385    operands1.append(Operand(type="SIMDReg", size=128, dest="Spare"))
7386
7387    operands2=[]
7388    operands2.append(Operand(type="Mem", size=64, dest="EA"))
7389    operands2.append(Operand(type="SIMDReg", size=128, dest="Spare"))
7390
7391    operands3=[]
7392    operands3.append(Operand(type="SIMDReg", size=128, dest="EA"))
7393    operands3.append(Operand(type="SIMDReg", size=256, dest="Spare"))
7394
7395    operands4=[]
7396    operands4.append(Operand(type="Mem", size=128, dest="EA"))
7397    operands4.append(Operand(type="SIMDReg", size=256, dest="Spare"))
7398
7399    if g == 'ph2ps':
7400        operands1.reverse()
7401        operands2.reverse()
7402        operands3.reverse()
7403        operands4.reverse()
7404        map = 0x38
7405    elif g == 'ps2ph':
7406        immop = Operand(type="Imm", size=8, relaxed=True, dest="Imm")
7407        operands1.append(immop)
7408        operands2.append(immop)
7409        operands3.append(immop)
7410        operands4.append(immop)
7411        map = 0x3A
7412
7413    add_group("avx_cvt" + g,
7414        cpu=["F16C", "AVX"],
7415        modifiers=["PreAdd", "Op2Add"],
7416        vex=128,
7417        prefix=0x00,
7418        opcode=[0x0F, map, 0x00],
7419        operands=operands1)
7420
7421    add_group("avx_cvt" + g,
7422        cpu=["F16C", "AVX"],
7423        modifiers=["PreAdd", "Op2Add"],
7424        vex=128,
7425        prefix=0x00,
7426        opcode=[0x0F, map, 0x00],
7427        operands=operands2)
7428
7429    add_group("avx_cvt" + g,
7430        cpu=["F16C", "AVX"],
7431        modifiers=["PreAdd", "Op2Add"],
7432        vex=256,
7433        prefix=0x00,
7434        opcode=[0x0F, map, 0x00],
7435        operands=operands3)
7436
7437    add_group("avx_cvt" + g,
7438        cpu=["F16C", "AVX"],
7439        modifiers=["PreAdd", "Op2Add"],
7440        vex=256,
7441        prefix=0x00,
7442        opcode=[0x0F, map, 0x00],
7443        operands=operands4)
7444
7445add_insn("vcvtps2ph", "avx_cvtps2ph", modifiers=[0x66, 0x1D], avx=True)
7446add_insn("vcvtph2ps", "avx_cvtph2ps", modifiers=[0x66, 0x13], avx=True)
7447
7448#####################################################################
7449# AMD SSE4a instructions
7450#####################################################################
7451
7452add_group("extrq",
7453    cpu=["SSE4a"],
7454    prefix=0x66,
7455    opcode=[0x0F, 0x78],
7456    operands=[Operand(type="SIMDReg", size=128, dest="EA"),
7457              Operand(type="Imm", size=8, relaxed=True, dest="EA"),
7458              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7459add_group("extrq",
7460    cpu=["SSE4a"],
7461    prefix=0x66,
7462    opcode=[0x0F, 0x79],
7463    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7464              Operand(type="SIMDReg", size=128, dest="EA")])
7465
7466add_insn("extrq", "extrq")
7467
7468add_group("insertq",
7469    cpu=["SSE4a"],
7470    prefix=0xF2,
7471    opcode=[0x0F, 0x78],
7472    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7473              Operand(type="SIMDReg", size=128, dest="EA"),
7474              Operand(type="Imm", size=8, relaxed=True, dest="EA"),
7475              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7476add_group("insertq",
7477    cpu=["SSE4a"],
7478    prefix=0xF2,
7479    opcode=[0x0F, 0x79],
7480    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7481              Operand(type="SIMDReg", size=128, dest="EA")])
7482
7483add_insn("insertq", "insertq")
7484
7485add_group("movntsd",
7486    cpu=["SSE4a"],
7487    prefix=0xF2,
7488    opcode=[0x0F, 0x2B],
7489    operands=[Operand(type="Mem", size=64, relaxed=True, dest="EA"),
7490              Operand(type="SIMDReg", size=128, dest="Spare")])
7491
7492add_insn("movntsd", "movntsd")
7493
7494add_group("movntss",
7495    cpu=["SSE4a"],
7496    prefix=0xF3,
7497    opcode=[0x0F, 0x2B],
7498    operands=[Operand(type="Mem", size=32, relaxed=True, dest="EA"),
7499              Operand(type="SIMDReg", size=128, dest="Spare")])
7500
7501add_insn("movntss", "movntss")
7502
7503#####################################################################
7504# AMD XOP instructions
7505#####################################################################
7506
7507add_group("vfrc_pdps",
7508    cpu=["XOP"],
7509    modifiers=["Op1Add"],
7510    xop=128,
7511    opcode=[0x09, 0x80],
7512    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7513              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7514add_group("vfrc_pdps",
7515    cpu=["XOP"],
7516    modifiers=["Op1Add"],
7517    xop=256,
7518    opcode=[0x09, 0x80],
7519    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7520              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
7521add_insn("vfrczpd", "vfrc_pdps", modifiers=[0x01])
7522add_insn("vfrczps", "vfrc_pdps", modifiers=[0x00])
7523
7524add_group("vfrczsd",
7525    cpu=["XOP"],
7526    xop=128,
7527    opcode=[0x09, 0x83],
7528    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7529              Operand(type="SIMDReg", size=128, dest="EA")])
7530add_group("vfrczsd",
7531    cpu=["XOP"],
7532    xop=128,
7533    opcode=[0x09, 0x83],
7534    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7535              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
7536add_insn("vfrczsd", "vfrczsd")
7537
7538add_group("vfrczss",
7539    cpu=["XOP"],
7540    xop=128,
7541    opcode=[0x09, 0x82],
7542    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7543              Operand(type="SIMDReg", size=128, dest="EA")])
7544add_group("vfrczss",
7545    cpu=["XOP"],
7546    xop=128,
7547    opcode=[0x09, 0x82],
7548    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7549              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
7550add_insn("vfrczss", "vfrczss")
7551
7552add_group("vpcmov",
7553    cpu=["XOP"],
7554    xop=128,
7555    xopw=0,
7556    opcode=[0x08, 0xA2],
7557    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7558              Operand(type="SIMDReg", size=128, dest="VEX"),
7559              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7560              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7561add_group("vpcmov",
7562    cpu=["XOP"],
7563    xop=128,
7564    xopw=1,
7565    opcode=[0x08, 0xA2],
7566    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7567              Operand(type="SIMDReg", size=128, dest="VEX"),
7568              Operand(type="SIMDReg", size=128, dest="VEXImmSrc"),
7569              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7570add_group("vpcmov",
7571    cpu=["XOP"],
7572    xop=256,
7573    xopw=0,
7574    opcode=[0x08, 0xA2],
7575    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7576              Operand(type="SIMDReg", size=256, dest="VEX"),
7577              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
7578              Operand(type="SIMDReg", size=256, dest="VEXImmSrc")])
7579add_group("vpcmov",
7580    cpu=["XOP"],
7581    xop=256,
7582    xopw=1,
7583    opcode=[0x08, 0xA2],
7584    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7585              Operand(type="SIMDReg", size=256, dest="VEX"),
7586              Operand(type="SIMDReg", size=256, dest="VEXImmSrc"),
7587              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
7588
7589add_insn("vpcmov", "vpcmov")
7590
7591add_group("vpcom",
7592    cpu=["XOP"],
7593    modifiers=["Op1Add", "Imm8"],
7594    xop=128,
7595    opcode=[0x08, 0x00],
7596    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7597              Operand(type="SIMDReg", size=128, dest="VEX"),
7598              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7599add_group("vpcom_imm",
7600    cpu=["XOP"],
7601    modifiers=["Op1Add"],
7602    xop=128,
7603    opcode=[0x08, 0x00],
7604    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7605              Operand(type="SIMDReg", size=128, dest="VEX"),
7606              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7607              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7608
7609for opc, sfx in [(0xCC, "b"),
7610                 (0xCE, "d"),
7611                 (0xCD, "w"),
7612                 (0xCF, "q"),
7613                 (0xEC, "ub"),
7614                 (0xEE, "ud"),
7615                 (0xEF, "uq"),
7616                 (0xED, "uw")]:
7617    add_insn("vpcom"+sfx, "vpcom_imm", modifiers=[opc])
7618    for ib, cc in enumerate(["lt", "le", "gt", "ge",
7619                             "eq", "neq", "false", "true"]):
7620        add_insn("vpcom"+cc+sfx, "vpcom", modifiers=[opc, ib])
7621    # ne alias for neq
7622    add_insn("vpcomne"+sfx, "vpcom", modifiers=[opc, 5])
7623
7624add_group("vphaddsub",
7625    cpu=["XOP"],
7626    modifiers=["Op1Add"],
7627    xop=128,
7628    opcode=[0x09, 0x00],
7629    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7630              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7631
7632add_insn("vphaddbw", "vphaddsub", modifiers=[0xC1])
7633add_insn("vphaddbd", "vphaddsub", modifiers=[0xC2])
7634add_insn("vphaddbq", "vphaddsub", modifiers=[0xC3])
7635add_insn("vphaddwd", "vphaddsub", modifiers=[0xC6])
7636add_insn("vphaddwq", "vphaddsub", modifiers=[0xC7])
7637add_insn("vphadddq", "vphaddsub", modifiers=[0xCB])
7638
7639add_insn("vphaddubw", "vphaddsub", modifiers=[0xD1])
7640add_insn("vphaddubd", "vphaddsub", modifiers=[0xD2])
7641add_insn("vphaddubq", "vphaddsub", modifiers=[0xD3])
7642add_insn("vphadduwd", "vphaddsub", modifiers=[0xD6])
7643add_insn("vphadduwq", "vphaddsub", modifiers=[0xD7])
7644add_insn("vphaddudq", "vphaddsub", modifiers=[0xD8])
7645
7646add_insn("vphsubbw", "vphaddsub", modifiers=[0xE1])
7647add_insn("vphsubwd", "vphaddsub", modifiers=[0xE2])
7648add_insn("vphsubdq", "vphaddsub", modifiers=[0xE3])
7649
7650add_group("vpma",
7651    cpu=["XOP"],
7652    modifiers=["Op1Add"],
7653    xop=128,
7654    opcode=[0x08, 0x00],
7655    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7656              Operand(type="SIMDReg", size=128, dest="VEX"),
7657              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7658              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7659
7660add_insn("vpmacsdd", "vpma", modifiers=[0x9E])
7661add_insn("vpmacsdqh", "vpma", modifiers=[0x9F])
7662add_insn("vpmacsdql", "vpma", modifiers=[0x97])
7663add_insn("vpmacssdd", "vpma", modifiers=[0x8E])
7664add_insn("vpmacssdqh", "vpma", modifiers=[0x8F])
7665add_insn("vpmacssdql", "vpma", modifiers=[0x87])
7666add_insn("vpmacsswd", "vpma", modifiers=[0x86])
7667add_insn("vpmacssww", "vpma", modifiers=[0x85])
7668add_insn("vpmacswd", "vpma", modifiers=[0x96])
7669add_insn("vpmacsww", "vpma", modifiers=[0x95])
7670add_insn("vpmadcsswd", "vpma", modifiers=[0xA6])
7671add_insn("vpmadcswd", "vpma", modifiers=[0xB6])
7672
7673add_group("vpperm",
7674    cpu=["XOP"],
7675    xop=128,
7676    xopw=0,
7677    opcode=[0x08, 0xA3],
7678    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7679              Operand(type="SIMDReg", size=128, dest="VEX"),
7680              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7681              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7682add_group("vpperm",
7683    cpu=["XOP"],
7684    xop=128,
7685    xopw=1,
7686    opcode=[0x08, 0xA3],
7687    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7688              Operand(type="SIMDReg", size=128, dest="VEX"),
7689              Operand(type="SIMDReg", size=128, dest="VEXImmSrc"),
7690              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7691add_insn("vpperm", "vpperm")
7692
7693add_group("vprot",
7694    cpu=["XOP"],
7695    modifiers=["Op1Add"],
7696    xop=128,
7697    xopw=0,
7698    opcode=[0x09, 0x90],
7699    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7700              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7701              Operand(type="SIMDReg", size=128, dest="VEX")])
7702add_group("vprot",
7703    cpu=["XOP"],
7704    modifiers=["Op1Add"],
7705    xop=128,
7706    xopw=1,
7707    opcode=[0x09, 0x90],
7708    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7709              Operand(type="SIMDReg", size=128, dest="VEX"),
7710              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7711add_group("vprot",
7712    cpu=["XOP"],
7713    modifiers=["Op1Add"],
7714    xop=128,
7715    opcode=[0x08, 0xC0],
7716    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7717              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7718              Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7719for opc, sfx in enumerate(["b", "w", "d", "q"]):
7720    add_insn("vprot"+sfx, "vprot", modifiers=[opc])
7721
7722add_group("amd_vpshift",
7723    cpu=["XOP"],
7724    modifiers=["Op1Add"],
7725    xop=128,
7726    xopw=0,
7727    opcode=[0x09, 0x00],
7728    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7729              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7730              Operand(type="SIMDReg", size=128, dest="VEX")])
7731add_group("amd_vpshift",
7732    cpu=["XOP"],
7733    modifiers=["Op1Add"],
7734    xop=128,
7735    xopw=1,
7736    opcode=[0x09, 0x00],
7737    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7738              Operand(type="SIMDReg", size=128, dest="VEX"),
7739              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7740for opc, sfx in enumerate(["b", "w", "d", "q"]):
7741    add_insn("vpsha"+sfx, "amd_vpshift", modifiers=[0x98+opc])
7742    add_insn("vpshl"+sfx, "amd_vpshift", modifiers=[0x94+opc])
7743
7744#####################################################################
7745# AMD FMA4 instructions (same as original Intel FMA instructions)
7746#####################################################################
7747
7748add_group("fma_128_256",
7749    cpu=["FMA4"],
7750    modifiers=["Op2Add"],
7751    vex=128,
7752    vexw=0,
7753    prefix=0x66,
7754    opcode=[0x0F, 0x3A, 0x00],
7755    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7756              Operand(type="SIMDReg", size=128, dest="VEX"),
7757              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
7758              Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7759add_group("fma_128_256",
7760    cpu=["FMA4"],
7761    modifiers=["Op2Add"],
7762    vex=128,
7763    vexw=1,
7764    prefix=0x66,
7765    opcode=[0x0F, 0x3A, 0x00],
7766    operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7767              Operand(type="SIMDReg", size=128, dest="VEX"),
7768              Operand(type="SIMDReg", size=128, dest="VEXImmSrc"),
7769              Operand(type="SIMDRM", size=128, relaxed=True, dest="EA")])
7770add_group("fma_128_256",
7771    cpu=["FMA4"],
7772    modifiers=["Op2Add"],
7773    vex=256,
7774    vexw=0,
7775    prefix=0x66,
7776    opcode=[0x0F, 0x3A, 0x00],
7777    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7778              Operand(type="SIMDReg", size=256, dest="VEX"),
7779              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA"),
7780              Operand(type="SIMDReg", size=256, dest="VEXImmSrc")])
7781add_group("fma_128_256",
7782    cpu=["FMA4"],
7783    modifiers=["Op2Add"],
7784    vex=256,
7785    vexw=1,
7786    prefix=0x66,
7787    opcode=[0x0F, 0x3A, 0x00],
7788    operands=[Operand(type="SIMDReg", size=256, dest="Spare"),
7789              Operand(type="SIMDReg", size=256, dest="VEX"),
7790              Operand(type="SIMDReg", size=256, dest="VEXImmSrc"),
7791              Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
7792
7793add_insn("vfmaddpd", "fma_128_256", modifiers=[0x69])
7794add_insn("vfmaddps", "fma_128_256", modifiers=[0x68])
7795add_insn("vfmaddsubpd", "fma_128_256", modifiers=[0x5D])
7796add_insn("vfmaddsubps", "fma_128_256", modifiers=[0x5C])
7797add_insn("vfmsubaddpd", "fma_128_256", modifiers=[0x5F])
7798add_insn("vfmsubaddps", "fma_128_256", modifiers=[0x5E])
7799add_insn("vfmsubpd", "fma_128_256", modifiers=[0x6D])
7800add_insn("vfmsubps", "fma_128_256", modifiers=[0x6C])
7801add_insn("vfnmaddpd", "fma_128_256", modifiers=[0x79])
7802add_insn("vfnmaddps", "fma_128_256", modifiers=[0x78])
7803add_insn("vfnmsubpd", "fma_128_256", modifiers=[0x7D])
7804add_insn("vfnmsubps", "fma_128_256", modifiers=[0x7C])
7805
7806for sz in [32, 64]:
7807    add_group("fma_128_m%d" % sz,
7808        cpu=["FMA4"],
7809        modifiers=["Op2Add"],
7810        vex=128,
7811        vexw=0,
7812        prefix=0x66,
7813        opcode=[0x0F, 0x3A, 0x00],
7814        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7815                  Operand(type="SIMDReg", size=128, dest="VEX"),
7816                  Operand(type="SIMDReg", size=128, dest="EA"),
7817                  Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7818    add_group("fma_128_m%d" % sz,
7819        cpu=["FMA4"],
7820        modifiers=["Op2Add"],
7821        vex=128,
7822        vexw=0,
7823        prefix=0x66,
7824        opcode=[0x0F, 0x3A, 0x00],
7825        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7826                  Operand(type="SIMDReg", size=128, dest="VEX"),
7827                  Operand(type="Mem", size=sz, relaxed=True, dest="EA"),
7828                  Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
7829    add_group("fma_128_m%d" % sz,
7830        cpu=["FMA4"],
7831        modifiers=["Op2Add"],
7832        vex=128,
7833        vexw=1,
7834        prefix=0x66,
7835        opcode=[0x0F, 0x3A, 0x00],
7836        operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
7837                  Operand(type="SIMDReg", size=128, dest="VEX"),
7838                  Operand(type="SIMDReg", size=128, dest="VEXImmSrc"),
7839                  Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
7840
7841add_insn("vfmaddsd", "fma_128_m64", modifiers=[0x6B])
7842add_insn("vfmaddss", "fma_128_m32", modifiers=[0x6A])
7843add_insn("vfmsubsd", "fma_128_m64", modifiers=[0x6F])
7844add_insn("vfmsubss", "fma_128_m32", modifiers=[0x6E])
7845add_insn("vfnmaddsd", "fma_128_m64", modifiers=[0x7B])
7846add_insn("vfnmaddss", "fma_128_m32", modifiers=[0x7A])
7847add_insn("vfnmsubsd", "fma_128_m64", modifiers=[0x7F])
7848add_insn("vfnmsubss", "fma_128_m32", modifiers=[0x7E])
7849
7850#####################################################################
7851# Intel XSAVE and XSAVEOPT instructions
7852#####################################################################
7853add_insn("xgetbv", "threebyte", modifiers=[0x0F, 0x01, 0xD0],
7854         cpu=["XSAVE", "386"])
7855add_insn("xsetbv", "threebyte", modifiers=[0x0F, 0x01, 0xD1],
7856         cpu=["XSAVE", "386", "Priv"])
7857add_insn("xsave", "twobytemem", modifiers=[4, 0x0F, 0xAE],
7858         cpu=["XSAVE", "386"])
7859add_insn("xrstor", "twobytemem", modifiers=[5, 0x0F, 0xAE],
7860         cpu=["XSAVE", "386"])
7861
7862add_insn("xsaveopt", "twobytemem", modifiers=[6, 0x0F, 0xAE],
7863         cpu=["XSAVEOPT"])
7864
7865add_group("xsaveopt64",
7866    modifiers=["SpAdd", "Op0Add", "Op1Add"],
7867    opcode=[0x00, 0x00],
7868    spare=0,
7869    opersize=64,
7870    operands=[Operand(type="Mem", relaxed=True, dest="EA")])
7871add_insn("xsaveopt64", "xsaveopt64", modifiers=[6, 0x0F, 0xAE],
7872         cpu=["XSAVEOPT"], only64=True)
7873
7874#####################################################################
7875# Intel MOVBE instruction
7876#####################################################################
7877for sz in (16, 32, 64):
7878    add_group("movbe",
7879        cpu=["MOVBE"],
7880        opersize=sz,
7881        opcode=[0x0F, 0x38, 0xF0],
7882        operands=[Operand(type="Reg", size=sz, dest="Spare"),
7883                  Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
7884    add_group("movbe",
7885        cpu=["MOVBE"],
7886        opersize=sz,
7887        opcode=[0x0F, 0x38, 0xF1],
7888        operands=[Operand(type="Mem", size=sz, relaxed=True, dest="EA"),
7889                  Operand(type="Reg", size=sz, dest="Spare")])
7890add_insn("movbe", "movbe")
7891
7892#####################################################################
7893# Intel advanced bit manipulations (BMI1/2)
7894#####################################################################
7895
7896add_insn("tzcnt", "cnt", modifiers=[0xBC], cpu=["BMI1"])
7897# LZCNT is present as AMD ext
7898
7899for sfx, sz in zip("wlq", [32, 64]):
7900    add_group("vex_gpr_ndd_rm_0F38_regext",
7901        suffix=sfx,
7902        modifiers=["PreAdd", "Op2Add", "SpAdd" ],
7903        opersize=sz,
7904        prefix=0x00,
7905        opcode=[0x0F, 0x38, 0x00],
7906        vex=0, ## VEX.L=0
7907        operands=[Operand(type="Reg", size=sz, dest="VEX"),
7908                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
7909
7910
7911add_insn("blsr",   "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 1],
7912         cpu=["BMI1"])
7913add_insn("blsmsk", "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 2],
7914         cpu=["BMI1"])
7915add_insn("blsi",   "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 3],
7916         cpu=["BMI1"])
7917
7918for sfx, sz in zip("wlq", [32, 64]):
7919    add_group("vex_gpr_reg_rm_0F_imm8",
7920        suffix=sfx,
7921        modifiers=["PreAdd", "Op1Add", "Op2Add"],
7922        opersize=sz,
7923        prefix=0x00,
7924        opcode=[0x0F, 0x00, 0x00],
7925        vex=0, ## VEX.L=0
7926        operands=[Operand(type="Reg", size=sz, dest="Spare"),
7927                  Operand(type="RM", size=sz, relaxed=True, dest="EA"),
7928                  Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
7929
7930add_insn("rorx", "vex_gpr_reg_rm_0F_imm8", modifiers=[0xF2, 0x3A, 0xF0],
7931         cpu=["BMI2"])
7932
7933for sfx, sz in zip("lq", [32, 64]):  # no 16-bit forms
7934    add_group("vex_gpr_reg_nds_rm_0F",
7935        suffix=sfx,
7936        modifiers=["PreAdd", "Op1Add", "Op2Add"],
7937        opersize=sz,
7938        prefix=0x00,
7939        opcode=[0x0F, 0x00, 0x00],
7940        vex=0,
7941        operands=[Operand(type="Reg", size=sz, dest="Spare"),
7942                  Operand(type="Reg", size=sz, dest="VEX"),
7943                  Operand(type="RM", size=sz, relaxed=True, dest="EA")])
7944
7945add_insn("andn", "vex_gpr_reg_nds_rm_0F", modifiers=[0x00, 0x38, 0xF2],
7946         cpu=["BMI1"])
7947
7948add_insn("pdep", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF2, 0x38, 0xF5],
7949         cpu=["BMI2"])
7950add_insn("pext", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF3, 0x38, 0xF5],
7951         cpu=["BMI2"])
7952
7953for sfx, sz in zip("lq", [32, 64]):  # no 16-bit forms
7954    add_group("vex_gpr_reg_rm_nds_0F",
7955        suffix=sfx,
7956        modifiers=["PreAdd", "Op1Add", "Op2Add"],
7957        opersize=sz,
7958        prefix=0x00,
7959        opcode=[0x0F, 0x00, 0x00],
7960        vex=0,
7961        operands=[Operand(type="Reg", size=sz, dest="Spare"),
7962                  Operand(type="RM", size=sz, relaxed=True, dest="EA"),
7963                  Operand(type="Reg", size=sz, dest="VEX")])
7964
7965add_insn("bzhi", "vex_gpr_reg_rm_nds_0F", modifiers=[0x00, 0x38, 0xF5],
7966         cpu=["BMI2"])
7967add_insn("bextr","vex_gpr_reg_rm_nds_0F", modifiers=[0x00, 0x38, 0xF7],
7968         cpu=["BMI1"])
7969add_insn("shlx", "vex_gpr_reg_rm_nds_0F", modifiers=[0x66, 0x38, 0xF7],
7970         cpu=["BMI2"])
7971add_insn("shrx", "vex_gpr_reg_rm_nds_0F", modifiers=[0xF2, 0x38, 0xF7],
7972         cpu=["BMI2"])
7973add_insn("sarx", "vex_gpr_reg_rm_nds_0F", modifiers=[0xF3, 0x38, 0xF7],
7974         cpu=["BMI2"])
7975
7976add_insn("mulx", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF2, 0x38, 0xF6],
7977         cpu=["BMI2"])
7978
7979
7980
7981#####################################################################
7982# Intel INVPCID instruction
7983#####################################################################
7984add_group("invpcid",
7985    cpu=["INVPCID", "Priv"],
7986    not64=True,
7987    prefix=0x66,
7988    opcode=[0x0F, 0x38, 0x82],
7989    operands=[Operand(type="Reg", size=32, dest="Spare"),
7990              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
7991add_group("invpcid",
7992    cpu=["INVPCID", "Priv"],
7993    only64=True,
7994    def_opersize_64=64,
7995    prefix=0x66,
7996    opcode=[0x0F, 0x38, 0x82],
7997    operands=[Operand(type="Reg", size=64, dest="Spare"),
7998              Operand(type="Mem", size=128, relaxed=True, dest="EA")])
7999add_insn("invpcid", "invpcid")
8000
8001#####################################################################
8002# AMD 3DNow! instructions
8003#####################################################################
8004
8005add_insn("prefetch", "twobytemem", modifiers=[0x00, 0x0F, 0x0D], cpu=["3DNow"])
8006add_insn("prefetchw", "twobytemem", modifiers=[0x01, 0x0F, 0x0D], cpu=["3DNow"])
8007add_insn("femms", "twobyte", modifiers=[0x0F, 0x0E], cpu=["3DNow"])
8008
8009add_group("now3d",
8010    cpu=["3DNow"],
8011    modifiers=["Imm8"],
8012    opcode=[0x0F, 0x0F],
8013    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
8014              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
8015
8016add_insn("pavgusb", "now3d", modifiers=[0xBF])
8017add_insn("pf2id", "now3d", modifiers=[0x1D])
8018add_insn("pf2iw", "now3d", modifiers=[0x1C], cpu=["Athlon", "3DNow"])
8019add_insn("pfacc", "now3d", modifiers=[0xAE])
8020add_insn("pfadd", "now3d", modifiers=[0x9E])
8021add_insn("pfcmpeq", "now3d", modifiers=[0xB0])
8022add_insn("pfcmpge", "now3d", modifiers=[0x90])
8023add_insn("pfcmpgt", "now3d", modifiers=[0xA0])
8024add_insn("pfmax", "now3d", modifiers=[0xA4])
8025add_insn("pfmin", "now3d", modifiers=[0x94])
8026add_insn("pfmul", "now3d", modifiers=[0xB4])
8027add_insn("pfnacc", "now3d", modifiers=[0x8A], cpu=["Athlon", "3DNow"])
8028add_insn("pfpnacc", "now3d", modifiers=[0x8E], cpu=["Athlon", "3DNow"])
8029add_insn("pfrcp", "now3d", modifiers=[0x96])
8030add_insn("pfrcpit1", "now3d", modifiers=[0xA6])
8031add_insn("pfrcpit2", "now3d", modifiers=[0xB6])
8032add_insn("pfrsqit1", "now3d", modifiers=[0xA7])
8033add_insn("pfrsqrt", "now3d", modifiers=[0x97])
8034add_insn("pfsub", "now3d", modifiers=[0x9A])
8035add_insn("pfsubr", "now3d", modifiers=[0xAA])
8036add_insn("pi2fd", "now3d", modifiers=[0x0D])
8037add_insn("pi2fw", "now3d", modifiers=[0x0C], cpu=["Athlon", "3DNow"])
8038add_insn("pmulhrwa", "now3d", modifiers=[0xB7])
8039add_insn("pswapd", "now3d", modifiers=[0xBB], cpu=["Athlon", "3DNow"])
8040
8041#####################################################################
8042# AMD extensions
8043#####################################################################
8044
8045add_insn("syscall", "twobyte", modifiers=[0x0F, 0x05], cpu=["686", "AMD"])
8046for sfx in [None, "l", "q"]:
8047    add_insn("sysret"+(sfx or ""), "twobyte", suffix=sfx, modifiers=[0x0F, 0x07],
8048             cpu=["686", "AMD", "Priv"])
8049add_insn("lzcnt", "cnt", modifiers=[0xBD], cpu=["LZCNT"])
8050
8051#####################################################################
8052# AMD x86-64 extensions
8053#####################################################################
8054
8055add_insn("swapgs", "threebyte", modifiers=[0x0F, 0x01, 0xF8], only64=True)
8056add_insn("rdtscp", "threebyte", modifiers=[0x0F, 0x01, 0xF9],
8057         cpu=["686", "AMD", "Priv"])
8058
8059add_group("cmpxchg16b",
8060    only64=True,
8061    opersize=64,
8062    opcode=[0x0F, 0xC7],
8063    spare=1,
8064    operands=[Operand(type="Mem", size=128, relaxed=True, dest="EA")])
8065
8066add_insn("cmpxchg16b", "cmpxchg16b")
8067
8068#####################################################################
8069# AMD Pacifica SVM instructions
8070#####################################################################
8071
8072add_insn("clgi", "threebyte", modifiers=[0x0F, 0x01, 0xDD], cpu=["SVM"])
8073add_insn("stgi", "threebyte", modifiers=[0x0F, 0x01, 0xDC], cpu=["SVM"])
8074add_insn("vmmcall", "threebyte", modifiers=[0x0F, 0x01, 0xD9], cpu=["SVM"])
8075
8076add_group("invlpga",
8077    cpu=["SVM"],
8078    opcode=[0x0F, 0x01, 0xDF],
8079    operands=[])
8080add_group("invlpga",
8081    cpu=["SVM"],
8082    opcode=[0x0F, 0x01, 0xDF],
8083    operands=[Operand(type="MemrAX", dest="AdSizeEA"),
8084              Operand(type="Creg", size=32, dest=None)])
8085
8086add_insn("invlpga", "invlpga")
8087
8088add_group("skinit",
8089    cpu=["SVM"],
8090    opcode=[0x0F, 0x01, 0xDE],
8091    operands=[])
8092add_group("skinit",
8093    cpu=["SVM"],
8094    opcode=[0x0F, 0x01, 0xDE],
8095    operands=[Operand(type="MemEAX", dest=None)])
8096
8097add_insn("skinit", "skinit")
8098
8099add_group("svm_rax",
8100    cpu=["SVM"],
8101    modifiers=["Op2Add"],
8102    opcode=[0x0F, 0x01, 0x00],
8103    operands=[])
8104add_group("svm_rax",
8105    cpu=["SVM"],
8106    modifiers=["Op2Add"],
8107    opcode=[0x0F, 0x01, 0x00],
8108    operands=[Operand(type="MemrAX", dest="AdSizeEA")])
8109
8110add_insn("vmload", "svm_rax", modifiers=[0xDA])
8111add_insn("vmrun", "svm_rax", modifiers=[0xD8])
8112add_insn("vmsave", "svm_rax", modifiers=[0xDB])
8113
8114#####################################################################
8115# VIA PadLock instructions
8116#####################################################################
8117
8118add_group("padlock",
8119    cpu=["PadLock"],
8120    modifiers=["Imm8", "PreAdd", "Op1Add"],
8121    prefix=0x00,
8122    opcode=[0x0F, 0x00],
8123    operands=[])
8124
8125add_insn("xstore", "padlock", modifiers=[0xC0, 0x00, 0xA7])
8126add_insn("xstorerng", "padlock", modifiers=[0xC0, 0x00, 0xA7])
8127add_insn("xcryptecb", "padlock", modifiers=[0xC8, 0xF3, 0xA7])
8128add_insn("xcryptcbc", "padlock", modifiers=[0xD0, 0xF3, 0xA7])
8129add_insn("xcryptctr", "padlock", modifiers=[0xD8, 0xF3, 0xA7])
8130add_insn("xcryptcfb", "padlock", modifiers=[0xE0, 0xF3, 0xA7])
8131add_insn("xcryptofb", "padlock", modifiers=[0xE8, 0xF3, 0xA7])
8132add_insn("montmul", "padlock", modifiers=[0xC0, 0xF3, 0xA6])
8133add_insn("xsha1", "padlock", modifiers=[0xC8, 0xF3, 0xA6])
8134add_insn("xsha256", "padlock", modifiers=[0xD0, 0xF3, 0xA6])
8135
8136#####################################################################
8137# Cyrix MMX instructions
8138#####################################################################
8139
8140add_group("cyrixmmx",
8141    cpu=["MMX", "Cyrix"],
8142    modifiers=["Op1Add"],
8143    opcode=[0x0F, 0x00],
8144    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
8145              Operand(type="SIMDRM", size=64, relaxed=True, dest="EA")])
8146
8147add_insn("paddsiw", "cyrixmmx", modifiers=[0x51])
8148add_insn("paveb", "cyrixmmx", modifiers=[0x50])
8149add_insn("pdistib", "cyrixmmx", modifiers=[0x54])
8150add_insn("pmagw", "cyrixmmx", modifiers=[0x52])
8151add_insn("pmulhriw", "cyrixmmx", modifiers=[0x5D])
8152add_insn("pmulhrwc", "cyrixmmx", modifiers=[0x59])
8153add_insn("pmvgezb", "cyrixmmx", modifiers=[0x5C])
8154add_insn("pmvlzb", "cyrixmmx", modifiers=[0x5B])
8155add_insn("pmvnzb", "cyrixmmx", modifiers=[0x5A])
8156add_insn("pmvzb", "cyrixmmx", modifiers=[0x58])
8157add_insn("psubsiw", "cyrixmmx", modifiers=[0x55])
8158
8159add_group("pmachriw",
8160    cpu=["MMX", "Cyrix"],
8161    opcode=[0x0F, 0x5E],
8162    operands=[Operand(type="SIMDReg", size=64, dest="Spare"),
8163              Operand(type="Mem", size=64, relaxed=True, dest="EA")])
8164
8165add_insn("pmachriw", "pmachriw")
8166
8167#####################################################################
8168# Cyrix extensions
8169#####################################################################
8170
8171add_insn("smint", "twobyte", modifiers=[0x0F, 0x38], cpu=["686", "Cyrix"])
8172add_insn("smintold", "twobyte", modifiers=[0x0F, 0x7E], cpu=["486", "Cyrix", "Obs"])
8173
8174add_group("rdwrshr",
8175    cpu=["Cyrix", "SMM", "686"],
8176    modifiers=["Op1Add"],
8177    opcode=[0x0F, 0x36],
8178    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA")])
8179
8180add_insn("rdshr", "rdwrshr", modifiers=[0x00])
8181add_insn("wrshr", "rdwrshr", modifiers=[0x01])
8182
8183add_group("rsdc",
8184    cpu=["Cyrix", "SMM", "486"],
8185    opcode=[0x0F, 0x79],
8186    operands=[Operand(type="SegReg", size=16, relaxed=True, dest="Spare"),
8187              Operand(type="Mem", size=80, relaxed=True, dest="EA")])
8188
8189add_insn("rsdc", "rsdc")
8190
8191add_group("cyrixsmm",
8192    cpu=["Cyrix", "SMM", "486"],
8193    modifiers=["Op1Add"],
8194    opcode=[0x0F, 0x00],
8195    operands=[Operand(type="Mem", size=80, relaxed=True, dest="EA")])
8196
8197add_insn("rsldt", "cyrixsmm", modifiers=[0x7B])
8198add_insn("rsts", "cyrixsmm", modifiers=[0x7D])
8199add_insn("svldt", "cyrixsmm", modifiers=[0x7A])
8200add_insn("svts", "cyrixsmm", modifiers=[0x7C])
8201
8202add_group("svdc",
8203    cpu=["Cyrix", "SMM", "486"],
8204    opcode=[0x0F, 0x78],
8205    operands=[Operand(type="Mem", size=80, relaxed=True, dest="EA"),
8206              Operand(type="SegReg", size=16, relaxed=True, dest="Spare")])
8207
8208add_insn("svdc", "svdc")
8209
8210#####################################################################
8211# Obsolete/undocumented instructions
8212#####################################################################
8213
8214add_insn("fsetpm", "twobyte", modifiers=[0xDB, 0xE4], cpu=["286", "FPU", "Obs"])
8215add_insn("loadall", "twobyte", modifiers=[0x0F, 0x07], cpu=["386", "Undoc"])
8216add_insn("loadall286", "twobyte", modifiers=[0x0F, 0x05], cpu=["286", "Undoc"])
8217add_insn("salc", "onebyte", modifiers=[0xD6], cpu=["Undoc"], not64=True)
8218add_insn("smi", "onebyte", modifiers=[0xF1], cpu=["386", "Undoc"])
8219
8220add_group("ibts",
8221    cpu=["Undoc", "Obs", "386"],
8222    opersize=16,
8223    opcode=[0x0F, 0xA7],
8224    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA"),
8225              Operand(type="Reg", size=16, dest="Spare")])
8226add_group("ibts",
8227    cpu=["Undoc", "Obs", "386"],
8228    opersize=32,
8229    opcode=[0x0F, 0xA7],
8230    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
8231              Operand(type="Reg", size=32, dest="Spare")])
8232
8233add_insn("ibts", "ibts")
8234
8235add_group("umov",
8236    cpu=["Undoc", "386"],
8237    opcode=[0x0F, 0x10],
8238    operands=[Operand(type="RM", size=8, relaxed=True, dest="EA"),
8239              Operand(type="Reg", size=8, dest="Spare")])
8240add_group("umov",
8241    cpu=["Undoc", "386"],
8242    opersize=16,
8243    opcode=[0x0F, 0x11],
8244    operands=[Operand(type="RM", size=16, relaxed=True, dest="EA"),
8245              Operand(type="Reg", size=16, dest="Spare")])
8246add_group("umov",
8247    cpu=["Undoc", "386"],
8248    opersize=32,
8249    opcode=[0x0F, 0x11],
8250    operands=[Operand(type="RM", size=32, relaxed=True, dest="EA"),
8251              Operand(type="Reg", size=32, dest="Spare")])
8252add_group("umov",
8253    cpu=["Undoc", "386"],
8254    opcode=[0x0F, 0x12],
8255    operands=[Operand(type="Reg", size=8, dest="Spare"),
8256              Operand(type="RM", size=8, relaxed=True, dest="EA")])
8257add_group("umov",
8258    cpu=["Undoc", "386"],
8259    opersize=16,
8260    opcode=[0x0F, 0x13],
8261    operands=[Operand(type="Reg", size=16, dest="Spare"),
8262              Operand(type="RM", size=16, relaxed=True, dest="EA")])
8263add_group("umov",
8264    cpu=["Undoc", "386"],
8265    opersize=32,
8266    opcode=[0x0F, 0x13],
8267    operands=[Operand(type="Reg", size=32, dest="Spare"),
8268              Operand(type="RM", size=32, relaxed=True, dest="EA")])
8269
8270add_insn("umov", "umov")
8271
8272add_group("xbts",
8273    cpu=["Undoc", "Obs", "386"],
8274    opersize=16,
8275    opcode=[0x0F, 0xA6],
8276    operands=[Operand(type="Reg", size=16, dest="Spare"),
8277              Operand(type="Mem", size=16, relaxed=True, dest="EA")])
8278add_group("xbts",
8279    cpu=["Undoc", "Obs", "386"],
8280    opersize=32,
8281    opcode=[0x0F, 0xA6],
8282    operands=[Operand(type="Reg", size=32, dest="Spare"),
8283              Operand(type="Mem", size=32, relaxed=True, dest="EA")])
8284
8285add_insn("xbts", "xbts")
8286
8287finalize_insns()
8288
8289#####################################################################
8290# Prefixes
8291#####################################################################
8292# operand size overrides
8293for sz in [16, 32, 64]:
8294    add_prefix("o%d" % sz, "OPERSIZE", sz, parser="nasm", only64=(sz==64))
8295    add_prefix("data%d" % sz, "OPERSIZE", sz, parser="gas", only64=(sz==64))
8296add_prefix("word",      "OPERSIZE", 16, parser="gas")
8297add_prefix("dword",     "OPERSIZE", 32, parser="gas")
8298add_prefix("qword",     "OPERSIZE", 64, parser="gas", only64=True)
8299
8300# address size overrides
8301for sz in [16, 32, 64]:
8302    add_prefix("a%d" % sz, "ADDRSIZE", sz, parser="nasm", only64=(sz==64))
8303    add_prefix("addr%d" % sz, "ADDRSIZE", sz, parser="gas", only64=(sz==64))
8304add_prefix("aword",     "ADDRSIZE", 16, parser="gas")
8305add_prefix("adword",    "ADDRSIZE", 32, parser="gas")
8306add_prefix("aqword",    "ADDRSIZE", 64, parser="gas", only64=True)
8307
8308# instruction prefixes
8309add_prefix("lock",      "LOCKREP",  0xF0)
8310add_prefix("repne",     "LOCKREP",  0xF2)
8311add_prefix("repnz",     "LOCKREP",  0xF2)
8312add_prefix("rep",       "LOCKREP",  0xF3)
8313add_prefix("repe",      "LOCKREP",  0xF3)
8314add_prefix("repz",      "LOCKREP",  0xF3)
8315
8316# other prefixes, limited to GAS-only at the moment
8317# Hint taken/not taken for jumps
8318add_prefix("ht",        "SEGREG",   0x3E, parser="gas")
8319add_prefix("hnt",       "SEGREG",   0x2E, parser="gas")
8320
8321# REX byte explicit prefixes
8322for val, suf in enumerate(["", "z", "y", "yz", "x", "xz", "xy", "xyz"]):
8323    add_prefix("rex" + suf, "REX", 0x40+val, parser="gas", only64=True)
8324    add_prefix("rex64" + suf, "REX", 0x48+val, parser="gas", only64=True)
8325
8326#####################################################################
8327# Output generation
8328#####################################################################
8329
8330out_dir = ""
8331if len(sys.argv) > 1:
8332  out_dir = sys.argv[1]
8333
8334output_groups(file(os.path.join(out_dir, "x86insns.c"), "wt"))
8335output_gas_insns(file(os.path.join(out_dir, "x86insn_gas.gperf"), "wt"))
8336output_nasm_insns(file(os.path.join(out_dir, "x86insn_nasm.gperf"), "wt"))
8337
8338