xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/X86InstrUtils.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric//===-- X86InstrUtils.td - X86 Instruction Utilities --------*- tablegen -*-===//
25f757f3fSDimitry Andric//
35f757f3fSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric//
75f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric//
95f757f3fSDimitry Andric// This file provides utilities for simplifying the instruction definitions.
105f757f3fSDimitry Andric//
115f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
125f757f3fSDimitry Andric
135f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
145f757f3fSDimitry Andric// Classes for setting the fields of X86Inst
155f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
165f757f3fSDimitry Andric
175f757f3fSDimitry Andric// Prefix byte classes which are used to indicate to the ad-hoc machine code
185f757f3fSDimitry Andric// emitter that various prefix bytes are required.
195f757f3fSDimitry Andricclass OpSize16 { OperandSize OpSize = OpSize16; }
205f757f3fSDimitry Andricclass OpSize32 { OperandSize OpSize = OpSize32; }
215f757f3fSDimitry Andricclass AdSize16 { AddressSize AdSize = AdSize16; }
225f757f3fSDimitry Andricclass AdSize32 { AddressSize AdSize = AdSize32; }
235f757f3fSDimitry Andricclass AdSize64 { AddressSize AdSize = AdSize64; }
245f757f3fSDimitry Andricclass REX_W  { bit hasREX_W = 1; }
255f757f3fSDimitry Andricclass LOCK   { bit hasLockPrefix = 1; }
265f757f3fSDimitry Andricclass REP    { bit hasREPPrefix = 1; }
275f757f3fSDimitry Andricclass TB     { Map OpMap = TB; }
285f757f3fSDimitry Andricclass T8     { Map OpMap = T8; }
295f757f3fSDimitry Andricclass TA     { Map OpMap = TA; }
305f757f3fSDimitry Andricclass T_MAP4 { Map OpMap = T_MAP4; }
315f757f3fSDimitry Andricclass T_MAP5 { Map OpMap = T_MAP5; }
325f757f3fSDimitry Andricclass T_MAP6 { Map OpMap = T_MAP6; }
335f757f3fSDimitry Andricclass T_MAP7 { Map OpMap = T_MAP7; }
34cb14a3feSDimitry Andricclass XOP8   { Map OpMap = XOP8; }
35cb14a3feSDimitry Andricclass XOP9   { Map OpMap = XOP9; }
36cb14a3feSDimitry Andricclass XOPA   { Map OpMap = XOPA; }
37cb14a3feSDimitry Andricclass ThreeDNow { Map OpMap = ThreeDNow; }
38cb14a3feSDimitry Andricclass PS { Prefix OpPrefix = PS; }
39cb14a3feSDimitry Andricclass PD { Prefix OpPrefix = PD; }
40cb14a3feSDimitry Andricclass XD { Prefix OpPrefix = XD; }
41cb14a3feSDimitry Andricclass XS { Prefix OpPrefix = XS; }
42647cbc5dSDimitry Andricclass XOP { Encoding OpEnc = EncXOP; }
435f757f3fSDimitry Andricclass VEX { Encoding OpEnc = EncVEX; }
44647cbc5dSDimitry Andricclass EVEX { Encoding OpEnc = EncEVEX; }
455f757f3fSDimitry Andricclass WIG  { bit IgnoresW = 1; }
465f757f3fSDimitry Andricclass VEX_L  { bit hasVEX_L = 1; }
475f757f3fSDimitry Andricclass VEX_LIG { bit ignoresVEX_L = 1; }
48cb14a3feSDimitry Andricclass VVVV { bit hasVEX_4V = 1; }
495f757f3fSDimitry Andricclass EVEX_K { bit hasEVEX_K = 1; }
505f757f3fSDimitry Andricclass EVEX_KZ : EVEX_K { bit hasEVEX_Z = 1; }
515f757f3fSDimitry Andricclass EVEX_B { bit hasEVEX_B = 1; }
52647cbc5dSDimitry Andricclass EVEX_NF { bit hasEVEX_NF = 1; }
535f757f3fSDimitry Andricclass EVEX_RC { bit hasEVEX_RC = 1; }
545f757f3fSDimitry Andricclass EVEX_V512 { bit hasEVEX_L2 = 1; bit hasVEX_L = 0; }
555f757f3fSDimitry Andricclass EVEX_V256 { bit hasEVEX_L2 = 0; bit hasVEX_L = 1; }
565f757f3fSDimitry Andricclass EVEX_V128 { bit hasEVEX_L2 = 0; bit hasVEX_L = 0; }
575f757f3fSDimitry Andricclass NOTRACK { bit hasNoTrackPrefix = 1; }
585f757f3fSDimitry Andricclass SIMD_EXC { list<Register> Uses = [MXCSR]; bit mayRaiseFPException = 1; }
595f757f3fSDimitry Andric// Specify AVX512 8-bit compressed displacement encoding based on the vector
605f757f3fSDimitry Andric// element size in bits (8, 16, 32, 64) and the CDisp8 form.
615f757f3fSDimitry Andricclass EVEX_CD8<int esize, CD8VForm form> {
625f757f3fSDimitry Andric  int CD8_EltSize = !srl(esize, 3);
635f757f3fSDimitry Andric  bits<3> CD8_Form = form.Value;
645f757f3fSDimitry Andric}
65cb14a3feSDimitry Andricclass NoCD8 { bits<7> CD8_Scale = 0; }
66647cbc5dSDimitry Andric
67cb14a3feSDimitry Andricclass AVX512BIi8Base : TB, PD {
685f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedInt;
695f757f3fSDimitry Andric  ImmType ImmT = Imm8;
705f757f3fSDimitry Andric}
71cb14a3feSDimitry Andricclass AVX512XSIi8Base : TB, XS {
725f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedInt;
735f757f3fSDimitry Andric  ImmType ImmT = Imm8;
745f757f3fSDimitry Andric}
75cb14a3feSDimitry Andricclass AVX512XDIi8Base : TB, XD {
765f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedInt;
775f757f3fSDimitry Andric  ImmType ImmT = Imm8;
785f757f3fSDimitry Andric}
79cb14a3feSDimitry Andricclass AVX512PSIi8Base : TB {
805f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedSingle;
815f757f3fSDimitry Andric  ImmType ImmT = Imm8;
825f757f3fSDimitry Andric}
83cb14a3feSDimitry Andricclass AVX512PDIi8Base : TB, PD {
845f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedDouble;
855f757f3fSDimitry Andric  ImmType ImmT = Imm8;
865f757f3fSDimitry Andric}
875f757f3fSDimitry Andricclass ExplicitREX2Prefix { ExplicitOpPrefix explicitOpPrefix = ExplicitREX2; }
885f757f3fSDimitry Andricclass ExplicitVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitVEX; }
895f757f3fSDimitry Andricclass ExplicitEVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitEVEX; }
90cb14a3feSDimitry Andricclass DefEFLAGS { list<Register> Defs = [EFLAGS]; }
91cb14a3feSDimitry Andricclass UseEFLAGS { list<Register> Uses = [EFLAGS]; }
92cb14a3feSDimitry Andricclass DisassembleOnly {
93cb14a3feSDimitry Andric  // The disassembler should know about this, but not the asmparser.
94cb14a3feSDimitry Andric  bit isCodeGenOnly = 1;
95cb14a3feSDimitry Andric  bit ForceDisassemble = 1;
96cb14a3feSDimitry Andric}
97cb14a3feSDimitry Andric
98647cbc5dSDimitry Andricdefvar unaryop_args = "$src1";
99647cbc5dSDimitry Andricdefvar unaryop_ndd_args = "{$src1, $dst|$dst, $src1}";
100647cbc5dSDimitry Andricdefvar binop_args = "{$src2, $src1|$src1, $src2}";
101647cbc5dSDimitry Andricdefvar binop_ndd_args = "{$src2, $src1, $dst|$dst, $src1, $src2}";
1027a6dacacSDimitry Andricdefvar binop_cl_args = "{%cl, $src1|$src1, cl}";
1037a6dacacSDimitry Andricdefvar binop_cl_ndd_args = "{%cl, $src1, $dst|$dst, $src1, cl}";
1047a6dacacSDimitry Andricdefvar triop_args = "{$src3, $src2, $src1|$src1, $src2, $src3}";
1057a6dacacSDimitry Andricdefvar triop_ndd_args = "{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}";
1067a6dacacSDimitry Andricdefvar triop_cl_args = "{%cl, $src2, $src1|$src1, $src2, cl}";
1077a6dacacSDimitry Andricdefvar triop_cl_ndd_args = "{%cl, $src2, $src1, $dst|$dst, $src1, $src2, cl}";
108647cbc5dSDimitry Andricdefvar tie_dst_src1 = "$src1 = $dst";
1095f757f3fSDimitry Andric
110647cbc5dSDimitry Andric// NDD - Helper for new data destination instructions
111647cbc5dSDimitry Andricclass NDD<bit ndd> {
112647cbc5dSDimitry Andric  string Constraints = !if(!eq(ndd, 0), tie_dst_src1, "");
113647cbc5dSDimitry Andric  Encoding OpEnc = !if(!eq(ndd, 0), EncNormal, EncEVEX);
114647cbc5dSDimitry Andric  bit hasEVEX_B = ndd;
115647cbc5dSDimitry Andric  bit hasVEX_4V = ndd;
116647cbc5dSDimitry Andric  Map OpMap = !if(!eq(ndd, 0), OB, T_MAP4);
117647cbc5dSDimitry Andric}
118647cbc5dSDimitry Andric// NF - Helper for NF (no flags update) instructions
1197a6dacacSDimitry Andricclass NF: T_MAP4, EVEX, EVEX_NF;
120647cbc5dSDimitry Andric// PL - Helper for promoted legacy instructions
1217a6dacacSDimitry Andricclass PL: T_MAP4, EVEX, ExplicitEVEXPrefix;
122*0fca6ea1SDimitry Andric// ZU - Helper for Zero Upper instructions
123*0fca6ea1SDimitry Andricclass ZU: T_MAP4, EVEX, EVEX_B;
1245f757f3fSDimitry Andric
1255f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
1265f757f3fSDimitry Andric// X86 Type infomation definitions
1275f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
1285f757f3fSDimitry Andric
1295f757f3fSDimitry Andric/// X86TypeInfo - This is a bunch of information that describes relevant X86
1305f757f3fSDimitry Andric/// information about value types.  For example, it can tell you what the
1315f757f3fSDimitry Andric/// register class and preferred load to use.
1325f757f3fSDimitry Andricclass X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
1335f757f3fSDimitry Andric                  PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
1345f757f3fSDimitry Andric                  Operand immoperand, SDPatternOperator immoperator,
1355f757f3fSDimitry Andric                  SDPatternOperator immnosuoperator, Operand imm8operand,
1365f757f3fSDimitry Andric                  SDPatternOperator imm8operator, SDPatternOperator imm8nosuoperator,
137cb14a3feSDimitry Andric                  bit hasEvenOpcode, bit hasREX_W> {
1385f757f3fSDimitry Andric  /// VT - This is the value type itself.
1395f757f3fSDimitry Andric  ValueType VT = vt;
1405f757f3fSDimitry Andric
1415f757f3fSDimitry Andric  /// InstrSuffix - This is the suffix used on instructions with this type.  For
1425f757f3fSDimitry Andric  /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
1435f757f3fSDimitry Andric  string InstrSuffix = instrsuffix;
1445f757f3fSDimitry Andric
1455f757f3fSDimitry Andric  /// RegClass - This is the register class associated with this type.  For
1465f757f3fSDimitry Andric  /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
1475f757f3fSDimitry Andric  RegisterClass RegClass = regclass;
1485f757f3fSDimitry Andric
1495f757f3fSDimitry Andric  /// LoadNode - This is the load node associated with this type.  For
1505f757f3fSDimitry Andric  /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
1515f757f3fSDimitry Andric  PatFrag LoadNode = loadnode;
1525f757f3fSDimitry Andric
1535f757f3fSDimitry Andric  /// MemOperand - This is the memory operand associated with this type.  For
1545f757f3fSDimitry Andric  /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
1555f757f3fSDimitry Andric  X86MemOperand MemOperand = memoperand;
1565f757f3fSDimitry Andric
1575f757f3fSDimitry Andric  /// ImmEncoding - This is the encoding of an immediate of this type.  For
1585f757f3fSDimitry Andric  /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32.  Note that i64 -> Imm32
1595f757f3fSDimitry Andric  /// since the immediate fields of i64 instructions is a 32-bit sign extended
1605f757f3fSDimitry Andric  /// value.
1615f757f3fSDimitry Andric  ImmType ImmEncoding = immkind;
1625f757f3fSDimitry Andric
1635f757f3fSDimitry Andric  /// ImmOperand - This is the operand kind of an immediate of this type.  For
1645f757f3fSDimitry Andric  /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm.  Note that i64 ->
1655f757f3fSDimitry Andric  /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
1665f757f3fSDimitry Andric  /// extended value.
1675f757f3fSDimitry Andric  Operand ImmOperand = immoperand;
1685f757f3fSDimitry Andric
1695f757f3fSDimitry Andric  /// ImmOperator - This is the operator that should be used to match an
1705f757f3fSDimitry Andric  /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
1715f757f3fSDimitry Andric  SDPatternOperator ImmOperator = immoperator;
1725f757f3fSDimitry Andric
1735f757f3fSDimitry Andric  SDPatternOperator ImmNoSuOperator = immnosuoperator;
1745f757f3fSDimitry Andric
1755f757f3fSDimitry Andric  /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
1765f757f3fSDimitry Andric  /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
1775f757f3fSDimitry Andric  /// only used for instructions that have a sign-extended imm8 field form.
1785f757f3fSDimitry Andric  Operand Imm8Operand = imm8operand;
1795f757f3fSDimitry Andric
1805f757f3fSDimitry Andric  /// Imm8Operator - This is the operator that should be used to match an 8-bit
1815f757f3fSDimitry Andric  /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
1825f757f3fSDimitry Andric  SDPatternOperator Imm8Operator = imm8operator;
1835f757f3fSDimitry Andric
1845f757f3fSDimitry Andric  SDPatternOperator Imm8NoSuOperator = imm8nosuoperator;
1855f757f3fSDimitry Andric
186cb14a3feSDimitry Andric  /// HasEvenOpcode - This bit is true if the instruction should have an even (as
187cb14a3feSDimitry Andric  /// opposed to odd) opcode.  Operations on i8 are even, operations on
188cb14a3feSDimitry Andric  /// other datatypes are usually odd.
189cb14a3feSDimitry Andric  bit HasEvenOpcode = hasEvenOpcode;
1905f757f3fSDimitry Andric
1915f757f3fSDimitry Andric  /// HasREX_W - This bit is set to true if the instruction should have
1925f757f3fSDimitry Andric  /// the 0x40 REX prefix.  This is set for i64 types.
1935f757f3fSDimitry Andric  bit HasREX_W = hasREX_W;
1945f757f3fSDimitry Andric}
1955f757f3fSDimitry Andric
1965f757f3fSDimitry Andricdef invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
1975f757f3fSDimitry Andric
1985f757f3fSDimitry Andricdef Xi8  : X86TypeInfo<i8, "b", GR8, loadi8, i8mem, Imm8, i8imm,
1995f757f3fSDimitry Andric                       imm_su, imm, i8imm, invalid_node, invalid_node,
200cb14a3feSDimitry Andric                       1, 0>;
2015f757f3fSDimitry Andricdef Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem, Imm16, i16imm,
2025f757f3fSDimitry Andric                       imm_su, imm, i16i8imm, i16immSExt8_su, i16immSExt8,
203cb14a3feSDimitry Andric                       0, 0>;
2045f757f3fSDimitry Andricdef Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem, Imm32, i32imm,
2055f757f3fSDimitry Andric                       imm_su, imm, i32i8imm, i32immSExt8_su, i32immSExt8,
206cb14a3feSDimitry Andric                       0, 0>;
2075f757f3fSDimitry Andricdef Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem, Imm32S, i64i32imm,
2085f757f3fSDimitry Andric                       i64immSExt32_su, i64immSExt32, i64i8imm, i64immSExt8_su,
209cb14a3feSDimitry Andric                       i64immSExt8, 0, 1>;
2105f757f3fSDimitry Andric
2115f757f3fSDimitry Andric// Group template arguments that can be derived from the vector type (EltNum x
2125f757f3fSDimitry Andric// EltVT).  These are things like the register class for the writemask, etc.
2135f757f3fSDimitry Andric// The idea is to pass one of these as the template argument rather than the
2145f757f3fSDimitry Andric// individual arguments.
2155f757f3fSDimitry Andric// The template is also used for scalar types, in this case numelts is 1.
2165f757f3fSDimitry Andricclass X86VectorVTInfo<int numelts, ValueType eltvt, RegisterClass rc,
2175f757f3fSDimitry Andric                      string suffix = ""> {
2185f757f3fSDimitry Andric  RegisterClass RC = rc;
2195f757f3fSDimitry Andric  ValueType EltVT = eltvt;
2205f757f3fSDimitry Andric  int NumElts = numelts;
2215f757f3fSDimitry Andric
2225f757f3fSDimitry Andric  // Corresponding mask register class.
2235f757f3fSDimitry Andric  RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
2245f757f3fSDimitry Andric
2255f757f3fSDimitry Andric  // Corresponding mask register pair class.
2265f757f3fSDimitry Andric  RegisterOperand KRPC = !if (!gt(NumElts, 16), ?,
2275f757f3fSDimitry Andric                              !cast<RegisterOperand>("VK" # NumElts # "Pair"));
2285f757f3fSDimitry Andric
2295f757f3fSDimitry Andric  // Corresponding write-mask register class.
2305f757f3fSDimitry Andric  RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
2315f757f3fSDimitry Andric
2325f757f3fSDimitry Andric  // The mask VT.
2335f757f3fSDimitry Andric  ValueType KVT = !cast<ValueType>("v" # NumElts # "i1");
2345f757f3fSDimitry Andric
2355f757f3fSDimitry Andric  // Suffix used in the instruction mnemonic.
2365f757f3fSDimitry Andric  string Suffix = suffix;
2375f757f3fSDimitry Andric
2385f757f3fSDimitry Andric  // VTName is a string name for vector VT. For vector types it will be
2395f757f3fSDimitry Andric  // v # NumElts # EltVT, so for vector of 8 elements of i32 it will be v8i32
2405f757f3fSDimitry Andric  // It is a little bit complex for scalar types, where NumElts = 1.
2415f757f3fSDimitry Andric  // In this case we build v4f32 or v2f64
2425f757f3fSDimitry Andric  string VTName = "v" # !if (!eq (NumElts, 1),
2435f757f3fSDimitry Andric                        !if (!eq (EltVT.Size, 16), 8,
2445f757f3fSDimitry Andric                        !if (!eq (EltVT.Size, 32), 4,
2455f757f3fSDimitry Andric                        !if (!eq (EltVT.Size, 64), 2, NumElts))), NumElts) # EltVT;
2465f757f3fSDimitry Andric
2475f757f3fSDimitry Andric  // The vector VT.
2485f757f3fSDimitry Andric  ValueType VT = !cast<ValueType>(VTName);
2495f757f3fSDimitry Andric
2505f757f3fSDimitry Andric  string EltTypeName = !cast<string>(EltVT);
2515f757f3fSDimitry Andric  // Size of the element type in bits, e.g. 32 for v16i32.
2525f757f3fSDimitry Andric  string EltSizeName = !subst("i", "", !subst("f", "", !subst("b", "", EltTypeName)));
2535f757f3fSDimitry Andric  int EltSize = EltVT.Size;
2545f757f3fSDimitry Andric
2555f757f3fSDimitry Andric  // "i" for integer types and "f" for floating-point types
2565f757f3fSDimitry Andric  string TypeVariantName = !subst("b", "", !subst(EltSizeName, "", EltTypeName));
2575f757f3fSDimitry Andric
2585f757f3fSDimitry Andric  // Size of RC in bits, e.g. 512 for VR512.
2595f757f3fSDimitry Andric  int Size = VT.Size;
2605f757f3fSDimitry Andric
2615f757f3fSDimitry Andric  // The corresponding memory operand, e.g. i512mem for VR512.
2625f757f3fSDimitry Andric  X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
2635f757f3fSDimitry Andric  X86MemOperand ScalarMemOp = !cast<X86MemOperand>(!subst("b", "", EltTypeName) # "mem");
2645f757f3fSDimitry Andric  // FP scalar memory operand for intrinsics - ssmem/sdmem.
2655f757f3fSDimitry Andric  Operand IntScalarMemOp = !if (!eq (EltTypeName, "f16"), !cast<Operand>("shmem"),
2665f757f3fSDimitry Andric                           !if (!eq (EltTypeName, "bf16"), !cast<Operand>("shmem"),
2675f757f3fSDimitry Andric                           !if (!eq (EltTypeName, "f32"), !cast<Operand>("ssmem"),
2685f757f3fSDimitry Andric                           !if (!eq (EltTypeName, "f64"), !cast<Operand>("sdmem"), ?))));
2695f757f3fSDimitry Andric
2705f757f3fSDimitry Andric  // Load patterns
2715f757f3fSDimitry Andric  PatFrag LdFrag = !cast<PatFrag>("load" # VTName);
2725f757f3fSDimitry Andric
2735f757f3fSDimitry Andric  PatFrag AlignedLdFrag = !cast<PatFrag>("alignedload" # VTName);
2745f757f3fSDimitry Andric
2755f757f3fSDimitry Andric  PatFrag ScalarLdFrag = !cast<PatFrag>("load" # !subst("b", "", EltTypeName));
2765f757f3fSDimitry Andric  PatFrag BroadcastLdFrag = !cast<PatFrag>("X86VBroadcastld" # EltSizeName);
2775f757f3fSDimitry Andric
2785f757f3fSDimitry Andric  PatFrags ScalarIntMemFrags = !if (!eq (EltTypeName, "f16"), !cast<PatFrags>("sse_load_f16"),
2795f757f3fSDimitry Andric                               !if (!eq (EltTypeName, "bf16"), !cast<PatFrags>("sse_load_f16"),
2805f757f3fSDimitry Andric                               !if (!eq (EltTypeName, "f32"), !cast<PatFrags>("sse_load_f32"),
2815f757f3fSDimitry Andric                               !if (!eq (EltTypeName, "f64"), !cast<PatFrags>("sse_load_f64"), ?))));
2825f757f3fSDimitry Andric
2835f757f3fSDimitry Andric  // The string to specify embedded broadcast in assembly.
2845f757f3fSDimitry Andric  string BroadcastStr = "{1to" # NumElts # "}";
2855f757f3fSDimitry Andric
2865f757f3fSDimitry Andric  // 8-bit compressed displacement tuple/subvector format.  This is only
2875f757f3fSDimitry Andric  // defined for NumElts <= 8.
2885f757f3fSDimitry Andric  CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0),
2895f757f3fSDimitry Andric                               !cast<CD8VForm>("CD8VT" # NumElts), ?);
2905f757f3fSDimitry Andric
2915f757f3fSDimitry Andric  SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
2925f757f3fSDimitry Andric                          !if (!eq (Size, 256), sub_ymm, ?));
2935f757f3fSDimitry Andric
2945f757f3fSDimitry Andric  Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
2955f757f3fSDimitry Andric                     !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
2965f757f3fSDimitry Andric                     !if (!eq (EltTypeName, "f16"), SSEPackedSingle, // FIXME?
2975f757f3fSDimitry Andric                     !if (!eq (EltTypeName, "bf16"), SSEPackedSingle, // FIXME?
2985f757f3fSDimitry Andric                     SSEPackedInt))));
2995f757f3fSDimitry Andric
3005f757f3fSDimitry Andric  RegisterClass FRC = !if (!eq (EltTypeName, "f32"), FR32X,
3015f757f3fSDimitry Andric                      !if (!eq (EltTypeName, "f16"), FR16X,
3025f757f3fSDimitry Andric                      !if (!eq (EltTypeName, "bf16"), FR16X,
3035f757f3fSDimitry Andric                      FR64X)));
3045f757f3fSDimitry Andric
3055f757f3fSDimitry Andric  dag ImmAllZerosV = (VT immAllZerosV);
3065f757f3fSDimitry Andric
3075f757f3fSDimitry Andric  string ZSuffix = !if (!eq (Size, 128), "Z128",
3085f757f3fSDimitry Andric                   !if (!eq (Size, 256), "Z256", "Z"));
3095f757f3fSDimitry Andric}
3105f757f3fSDimitry Andric
3115f757f3fSDimitry Andricdef v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
3125f757f3fSDimitry Andricdef v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
3135f757f3fSDimitry Andricdef v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
3145f757f3fSDimitry Andricdef v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
3155f757f3fSDimitry Andricdef v32f16_info : X86VectorVTInfo<32, f16, VR512, "ph">;
3165f757f3fSDimitry Andricdef v32bf16_info: X86VectorVTInfo<32, bf16, VR512, "pbf">;
3175f757f3fSDimitry Andricdef v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
3185f757f3fSDimitry Andricdef v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
3195f757f3fSDimitry Andric
3205f757f3fSDimitry Andric// "x" in v32i8x_info means RC = VR256X
3215f757f3fSDimitry Andricdef v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
3225f757f3fSDimitry Andricdef v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
3235f757f3fSDimitry Andricdef v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
3245f757f3fSDimitry Andricdef v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
3255f757f3fSDimitry Andricdef v16f16x_info : X86VectorVTInfo<16, f16, VR256X, "ph">;
3265f757f3fSDimitry Andricdef v16bf16x_info: X86VectorVTInfo<16, bf16, VR256X, "pbf">;
3275f757f3fSDimitry Andricdef v8f32x_info  : X86VectorVTInfo<8,  f32, VR256X, "ps">;
3285f757f3fSDimitry Andricdef v4f64x_info  : X86VectorVTInfo<4,  f64, VR256X, "pd">;
3295f757f3fSDimitry Andric
3305f757f3fSDimitry Andricdef v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
3315f757f3fSDimitry Andricdef v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
3325f757f3fSDimitry Andricdef v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
3335f757f3fSDimitry Andricdef v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
3345f757f3fSDimitry Andricdef v8f16x_info  : X86VectorVTInfo<8,  f16, VR128X, "ph">;
3355f757f3fSDimitry Andricdef v8bf16x_info : X86VectorVTInfo<8,  bf16, VR128X, "pbf">;
3365f757f3fSDimitry Andricdef v4f32x_info  : X86VectorVTInfo<4,  f32, VR128X, "ps">;
3375f757f3fSDimitry Andricdef v2f64x_info  : X86VectorVTInfo<2,  f64, VR128X, "pd">;
3385f757f3fSDimitry Andric
3395f757f3fSDimitry Andric// We map scalar types to the smallest (128-bit) vector type
3405f757f3fSDimitry Andric// with the appropriate element type. This allows to use the same masking logic.
3415f757f3fSDimitry Andricdef i32x_info    : X86VectorVTInfo<1,  i32, GR32, "si">;
3425f757f3fSDimitry Andricdef i64x_info    : X86VectorVTInfo<1,  i64, GR64, "sq">;
3435f757f3fSDimitry Andricdef f16x_info    : X86VectorVTInfo<1,  f16, VR128X, "sh">;
3445f757f3fSDimitry Andricdef bf16x_info   : X86VectorVTInfo<1,  bf16, VR128X, "sbf">;
3455f757f3fSDimitry Andricdef f32x_info    : X86VectorVTInfo<1,  f32, VR128X, "ss">;
3465f757f3fSDimitry Andricdef f64x_info    : X86VectorVTInfo<1,  f64, VR128X, "sd">;
3475f757f3fSDimitry Andric
3485f757f3fSDimitry Andricclass AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
3495f757f3fSDimitry Andric                           X86VectorVTInfo i128> {
3505f757f3fSDimitry Andric  X86VectorVTInfo info512 = i512;
3515f757f3fSDimitry Andric  X86VectorVTInfo info256 = i256;
3525f757f3fSDimitry Andric  X86VectorVTInfo info128 = i128;
3535f757f3fSDimitry Andric}
3545f757f3fSDimitry Andric
3555f757f3fSDimitry Andricdef avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
3565f757f3fSDimitry Andric                                             v16i8x_info>;
3575f757f3fSDimitry Andricdef avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
3585f757f3fSDimitry Andric                                             v8i16x_info>;
3595f757f3fSDimitry Andricdef avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
3605f757f3fSDimitry Andric                                             v4i32x_info>;
3615f757f3fSDimitry Andricdef avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
3625f757f3fSDimitry Andric                                             v2i64x_info>;
3635f757f3fSDimitry Andricdef avx512vl_f16_info : AVX512VLVectorVTInfo<v32f16_info, v16f16x_info,
3645f757f3fSDimitry Andric                                             v8f16x_info>;
3655f757f3fSDimitry Andricdef avx512vl_bf16_info : AVX512VLVectorVTInfo<v32bf16_info, v16bf16x_info,
3665f757f3fSDimitry Andric                                             v8bf16x_info>;
3675f757f3fSDimitry Andricdef avx512vl_f32_info : AVX512VLVectorVTInfo<v16f32_info, v8f32x_info,
3685f757f3fSDimitry Andric                                             v4f32x_info>;
3695f757f3fSDimitry Andricdef avx512vl_f64_info : AVX512VLVectorVTInfo<v8f64_info, v4f64x_info,
3705f757f3fSDimitry Andric                                             v2f64x_info>;
3715f757f3fSDimitry Andric
3725f757f3fSDimitry Andricclass X86KVectorVTInfo<RegisterClass _krc, RegisterClass _krcwm,
3735f757f3fSDimitry Andric                       ValueType _vt> {
3745f757f3fSDimitry Andric  RegisterClass KRC = _krc;
3755f757f3fSDimitry Andric  RegisterClass KRCWM = _krcwm;
3765f757f3fSDimitry Andric  ValueType KVT = _vt;
3775f757f3fSDimitry Andric}
3785f757f3fSDimitry Andric
3795f757f3fSDimitry Andricdef v1i1_info : X86KVectorVTInfo<VK1, VK1WM, v1i1>;
3805f757f3fSDimitry Andricdef v2i1_info : X86KVectorVTInfo<VK2, VK2WM, v2i1>;
3815f757f3fSDimitry Andricdef v4i1_info : X86KVectorVTInfo<VK4, VK4WM, v4i1>;
3825f757f3fSDimitry Andricdef v8i1_info : X86KVectorVTInfo<VK8, VK8WM, v8i1>;
3835f757f3fSDimitry Andricdef v16i1_info : X86KVectorVTInfo<VK16, VK16WM, v16i1>;
3845f757f3fSDimitry Andricdef v32i1_info : X86KVectorVTInfo<VK32, VK32WM, v32i1>;
3855f757f3fSDimitry Andricdef v64i1_info : X86KVectorVTInfo<VK64, VK64WM, v64i1>;
3865f757f3fSDimitry Andric
3875f757f3fSDimitry Andric// Subclasses of X86Inst
3885f757f3fSDimitry Andricclass PseudoI<dag oops, dag iops, list<dag> pattern>
3895f757f3fSDimitry Andric  : X86Inst<0, Pseudo, NoImm, oops, iops, ""> {
3905f757f3fSDimitry Andric  let Pattern = pattern;
3915f757f3fSDimitry Andric}
3925f757f3fSDimitry Andric
3935f757f3fSDimitry Andricclass I<bits<8> o, Format f, dag outs, dag ins, string asm,
3945f757f3fSDimitry Andric        list<dag> pattern, Domain d = GenericDomain>
3955f757f3fSDimitry Andric  : X86Inst<o, f, NoImm, outs, ins, asm, d> {
3965f757f3fSDimitry Andric  let Pattern = pattern;
3975f757f3fSDimitry Andric}
3985f757f3fSDimitry Andricclass Ii8<bits<8> o, Format f, dag outs, dag ins, string asm,
3995f757f3fSDimitry Andric          list<dag> pattern, Domain d = GenericDomain>
4005f757f3fSDimitry Andric  : X86Inst<o, f, Imm8, outs, ins, asm, d> {
4015f757f3fSDimitry Andric  let Pattern = pattern;
4025f757f3fSDimitry Andric}
4035f757f3fSDimitry Andricclass Ii8Reg<bits<8> o, Format f, dag outs, dag ins, string asm,
4045f757f3fSDimitry Andric             list<dag> pattern, Domain d = GenericDomain>
4055f757f3fSDimitry Andric  : X86Inst<o, f, Imm8Reg, outs, ins, asm, d> {
4065f757f3fSDimitry Andric  let Pattern = pattern;
4075f757f3fSDimitry Andric}
4085f757f3fSDimitry Andricclass Ii8PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
4095f757f3fSDimitry Andric               list<dag> pattern>
4105f757f3fSDimitry Andric  : X86Inst<o, f, Imm8PCRel, outs, ins, asm> {
4115f757f3fSDimitry Andric  let Pattern = pattern;
4125f757f3fSDimitry Andric}
4135f757f3fSDimitry Andricclass Ii16<bits<8> o, Format f, dag outs, dag ins, string asm,
4145f757f3fSDimitry Andric           list<dag> pattern>
4155f757f3fSDimitry Andric  : X86Inst<o, f, Imm16, outs, ins, asm> {
4165f757f3fSDimitry Andric  let Pattern = pattern;
4175f757f3fSDimitry Andric}
4185f757f3fSDimitry Andricclass Ii32<bits<8> o, Format f, dag outs, dag ins, string asm,
4195f757f3fSDimitry Andric           list<dag> pattern>
4205f757f3fSDimitry Andric  : X86Inst<o, f, Imm32, outs, ins, asm> {
4215f757f3fSDimitry Andric  let Pattern = pattern;
4225f757f3fSDimitry Andric}
4235f757f3fSDimitry Andricclass Ii32S<bits<8> o, Format f, dag outs, dag ins, string asm,
4245f757f3fSDimitry Andric            list<dag> pattern>
4255f757f3fSDimitry Andric  : X86Inst<o, f, Imm32S, outs, ins, asm> {
4265f757f3fSDimitry Andric  let Pattern = pattern;
4275f757f3fSDimitry Andric}
4285f757f3fSDimitry Andric
4295f757f3fSDimitry Andricclass Ii64<bits<8> o, Format f, dag outs, dag ins, string asm,
4305f757f3fSDimitry Andric           list<dag> pattern>
4315f757f3fSDimitry Andric  : X86Inst<o, f, Imm64, outs, ins, asm> {
4325f757f3fSDimitry Andric  let Pattern = pattern;
4335f757f3fSDimitry Andric}
4345f757f3fSDimitry Andric
4355f757f3fSDimitry Andricclass Ii16PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
4365f757f3fSDimitry Andric           list<dag> pattern>
4375f757f3fSDimitry Andric           : X86Inst<o, f, Imm16PCRel, outs, ins, asm> {
4385f757f3fSDimitry Andric  let Pattern = pattern;
4395f757f3fSDimitry Andric}
4405f757f3fSDimitry Andric
4415f757f3fSDimitry Andricclass Ii32PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
4425f757f3fSDimitry Andric           list<dag> pattern>
4435f757f3fSDimitry Andric  : X86Inst<o, f, Imm32PCRel, outs, ins, asm> {
4445f757f3fSDimitry Andric  let Pattern = pattern;
4455f757f3fSDimitry Andric}
4465f757f3fSDimitry Andric
4475f757f3fSDimitry Andric// FPStack Instruction Templates:
4485f757f3fSDimitry Andric// FPI - Floating Point Instruction template.
4495f757f3fSDimitry Andricclass FPI<bits<8> o, Format F, dag outs, dag ins, string asm>
4505f757f3fSDimitry Andric  : I<o, F, outs, ins, asm, []> {
4515f757f3fSDimitry Andric  let Defs = [FPSW];
4525f757f3fSDimitry Andric  let Predicates = [HasX87];
4535f757f3fSDimitry Andric}
4545f757f3fSDimitry Andric
4555f757f3fSDimitry Andric// FpI_ - Floating Point Pseudo Instruction template.
4565f757f3fSDimitry Andricclass FpI_<dag outs, dag ins, FPFormat fp, list<dag> pattern>
4575f757f3fSDimitry Andric  : PseudoI<outs, ins, pattern> {
4585f757f3fSDimitry Andric  let FPForm = fp;
4595f757f3fSDimitry Andric  let Defs = [FPSW];
4605f757f3fSDimitry Andric  let Predicates = [HasX87];
4615f757f3fSDimitry Andric}
4625f757f3fSDimitry Andric
4635f757f3fSDimitry Andric// Templates for instructions that use a 16- or 32-bit segmented address as
4645f757f3fSDimitry Andric//  their only operand: lcall (FAR CALL) and ljmp (FAR JMP)
4655f757f3fSDimitry Andric//
4665f757f3fSDimitry Andric//   Iseg16 - 16-bit segment selector, 16-bit offset
4675f757f3fSDimitry Andric//   Iseg32 - 16-bit segment selector, 32-bit offset
4685f757f3fSDimitry Andric
4695f757f3fSDimitry Andricclass Iseg16 <bits<8> o, Format f, dag outs, dag ins, string asm,
4705f757f3fSDimitry Andric              list<dag> pattern>
4715f757f3fSDimitry Andric      : X86Inst<o, f, Imm16, outs, ins, asm> {
4725f757f3fSDimitry Andric  let Pattern = pattern;
4735f757f3fSDimitry Andric}
4745f757f3fSDimitry Andric
4755f757f3fSDimitry Andricclass Iseg32 <bits<8> o, Format f, dag outs, dag ins, string asm,
4765f757f3fSDimitry Andric              list<dag> pattern>
4775f757f3fSDimitry Andric      : X86Inst<o, f, Imm32, outs, ins, asm> {
4785f757f3fSDimitry Andric  let Pattern = pattern;
4795f757f3fSDimitry Andric}
4805f757f3fSDimitry Andric
4815f757f3fSDimitry Andric// SI - SSE 1 & 2 scalar instructions
4825f757f3fSDimitry Andricclass SI<bits<8> o, Format F, dag outs, dag ins, string asm,
4835f757f3fSDimitry Andric         list<dag> pattern, Domain d = GenericDomain>
4845f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, d> {
4855f757f3fSDimitry Andric  let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512],
4865f757f3fSDimitry Andric                   !if(!eq(OpEnc.Value, EncVEX.Value), [UseAVX],
4875f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1],
4885f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, XD.Value), [UseSSE2],
4895f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2],
4905f757f3fSDimitry Andric                   [UseSSE1])))));
4915f757f3fSDimitry Andric
4925f757f3fSDimitry Andric  // AVX instructions have a 'v' prefix in the mnemonic
4935f757f3fSDimitry Andric  let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm),
4945f757f3fSDimitry Andric                  !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm),
4955f757f3fSDimitry Andric                  asm));
4965f757f3fSDimitry Andric}
4975f757f3fSDimitry Andric
4985f757f3fSDimitry Andric// SI - SSE 1 & 2 scalar intrinsics - vex form available on AVX512
4995f757f3fSDimitry Andricclass SI_Int<bits<8> o, Format F, dag outs, dag ins, string asm,
5005f757f3fSDimitry Andric         list<dag> pattern, Domain d = GenericDomain>
5015f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, d> {
5025f757f3fSDimitry Andric  let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512],
5035f757f3fSDimitry Andric                   !if(!eq(OpEnc.Value, EncVEX.Value), [UseAVX],
5045f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1],
5055f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, XD.Value), [UseSSE2],
5065f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2],
5075f757f3fSDimitry Andric                   [UseSSE1])))));
5085f757f3fSDimitry Andric
5095f757f3fSDimitry Andric  // AVX instructions have a 'v' prefix in the mnemonic
5105f757f3fSDimitry Andric  let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm),
5115f757f3fSDimitry Andric                  !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm),
5125f757f3fSDimitry Andric                  asm));
5135f757f3fSDimitry Andric}
5145f757f3fSDimitry Andric// SIi8 - SSE 1 & 2 scalar instructions - vex form available on AVX512
5155f757f3fSDimitry Andricclass SIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
5165f757f3fSDimitry Andric           list<dag> pattern>
5175f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern> {
5185f757f3fSDimitry Andric  let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512],
5195f757f3fSDimitry Andric                   !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX],
5205f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1],
5215f757f3fSDimitry Andric                   [UseSSE2])));
5225f757f3fSDimitry Andric
5235f757f3fSDimitry Andric  // AVX instructions have a 'v' prefix in the mnemonic
5245f757f3fSDimitry Andric  let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm),
5255f757f3fSDimitry Andric                  !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm),
5265f757f3fSDimitry Andric                  asm));
5275f757f3fSDimitry Andric}
5285f757f3fSDimitry Andric
5295f757f3fSDimitry Andric// PI - SSE 1 & 2 packed instructions
5305f757f3fSDimitry Andricclass PI<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern,
5315f757f3fSDimitry Andric         Domain d>
5325f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, d> {
5335f757f3fSDimitry Andric  let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512],
5345f757f3fSDimitry Andric                   !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX],
5355f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2],
5365f757f3fSDimitry Andric                   [UseSSE1])));
5375f757f3fSDimitry Andric
5385f757f3fSDimitry Andric  // AVX instructions have a 'v' prefix in the mnemonic
5395f757f3fSDimitry Andric  let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm),
5405f757f3fSDimitry Andric                  !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm),
5415f757f3fSDimitry Andric                  asm));
5425f757f3fSDimitry Andric}
5435f757f3fSDimitry Andric
5445f757f3fSDimitry Andric// MMXPI - SSE 1 & 2 packed instructions with MMX operands
5455f757f3fSDimitry Andricclass MMXPI<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern,
5465f757f3fSDimitry Andric            Domain d>
5475f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, d> {
5485f757f3fSDimitry Andric  let Predicates = !if(!eq(OpPrefix.Value, PD.Value), [HasMMX, HasSSE2],
5495f757f3fSDimitry Andric                       [HasMMX, HasSSE1]);
5505f757f3fSDimitry Andric}
5515f757f3fSDimitry Andric
5525f757f3fSDimitry Andric// PIi8 - SSE 1 & 2 packed instructions with immediate
5535f757f3fSDimitry Andricclass PIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
5545f757f3fSDimitry Andric           list<dag> pattern, Domain d>
5555f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, d> {
5565f757f3fSDimitry Andric  let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512],
5575f757f3fSDimitry Andric                   !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX],
5585f757f3fSDimitry Andric                   !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2],
5595f757f3fSDimitry Andric                   [UseSSE1])));
5605f757f3fSDimitry Andric
5615f757f3fSDimitry Andric  // AVX instructions have a 'v' prefix in the mnemonic
5625f757f3fSDimitry Andric  let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm),
5635f757f3fSDimitry Andric                  !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm),
5645f757f3fSDimitry Andric                  asm));
5655f757f3fSDimitry Andric}
5665f757f3fSDimitry Andric
5675f757f3fSDimitry Andric// SSE1 Instruction Templates:
5685f757f3fSDimitry Andric//
5695f757f3fSDimitry Andric//   SSI   - SSE1 instructions with XS prefix.
5705f757f3fSDimitry Andric//   PSI   - SSE1 instructions with PS prefix.
5715f757f3fSDimitry Andric//   PSIi8 - SSE1 instructions with ImmT == Imm8 and PS prefix.
5725f757f3fSDimitry Andric//   VSSI  - SSE1 instructions with XS prefix in AVX form.
5735f757f3fSDimitry Andric//   VPSI  - SSE1 instructions with PS prefix in AVX form, packed single.
5745f757f3fSDimitry Andric
5755f757f3fSDimitry Andricclass SSI<bits<8> o, Format F, dag outs, dag ins, string asm,
5765f757f3fSDimitry Andric          list<dag> pattern>
577cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE1]>;
5785f757f3fSDimitry Andricclass SSIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
5795f757f3fSDimitry Andric            list<dag> pattern>
580cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE1]>;
5815f757f3fSDimitry Andricclass PSI<bits<8> o, Format F, dag outs, dag ins, string asm,
5825f757f3fSDimitry Andric          list<dag> pattern>
583cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
5845f757f3fSDimitry Andric        Requires<[UseSSE1]>;
5855f757f3fSDimitry Andricclass PSIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
5865f757f3fSDimitry Andric            list<dag> pattern>
587cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
5885f757f3fSDimitry Andric        Requires<[UseSSE1]>;
5895f757f3fSDimitry Andricclass VSSI<bits<8> o, Format F, dag outs, dag ins, string asm,
5905f757f3fSDimitry Andric           list<dag> pattern>
591cb14a3feSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XS,
5925f757f3fSDimitry Andric        Requires<[HasAVX]>;
5935f757f3fSDimitry Andricclass VPSI<bits<8> o, Format F, dag outs, dag ins, string asm,
5945f757f3fSDimitry Andric           list<dag> pattern>
595cb14a3feSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern, SSEPackedSingle>,
596cb14a3feSDimitry Andric        TB, Requires<[HasAVX]>;
5975f757f3fSDimitry Andric
5985f757f3fSDimitry Andric// SSE2 Instruction Templates:
5995f757f3fSDimitry Andric//
6005f757f3fSDimitry Andric//   SDI    - SSE2 instructions with XD prefix.
6015f757f3fSDimitry Andric//   SDIi8  - SSE2 instructions with ImmT == Imm8 and XD prefix.
6025f757f3fSDimitry Andric//   S2SI   - SSE2 instructions with XS prefix.
6035f757f3fSDimitry Andric//   SSDIi8 - SSE2 instructions with ImmT == Imm8 and XS prefix.
6045f757f3fSDimitry Andric//   PDI    - SSE2 instructions with PD prefix, packed double domain.
6055f757f3fSDimitry Andric//   PDIi8  - SSE2 instructions with ImmT == Imm8 and PD prefix.
6065f757f3fSDimitry Andric//   VSDI   - SSE2 scalar instructions with XD prefix in AVX form.
6075f757f3fSDimitry Andric//   VPDI   - SSE2 vector instructions with PD prefix in AVX form,
6085f757f3fSDimitry Andric//                 packed double domain.
6095f757f3fSDimitry Andric//   VS2I   - SSE2 scalar instructions with PD prefix in AVX form.
6105f757f3fSDimitry Andric//   S2I    - SSE2 scalar instructions with PD prefix.
6115f757f3fSDimitry Andric//   MMXSDIi8  - SSE2 instructions with ImmT == Imm8 and XD prefix as well as
6125f757f3fSDimitry Andric//               MMX operands.
6135f757f3fSDimitry Andric//   MMXSSDIi8 - SSE2 instructions with ImmT == Imm8 and XS prefix as well as
6145f757f3fSDimitry Andric//               MMX operands.
6155f757f3fSDimitry Andric
6165f757f3fSDimitry Andricclass SDI<bits<8> o, Format F, dag outs, dag ins, string asm,
6175f757f3fSDimitry Andric          list<dag> pattern>
618cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[UseSSE2]>;
6195f757f3fSDimitry Andricclass SDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
6205f757f3fSDimitry Andric            list<dag> pattern>
621cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[UseSSE2]>;
6225f757f3fSDimitry Andricclass S2SI<bits<8> o, Format F, dag outs, dag ins, string asm,
6235f757f3fSDimitry Andric           list<dag> pattern>
624cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE2]>;
6255f757f3fSDimitry Andricclass S2SIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
6265f757f3fSDimitry Andric             list<dag> pattern>
627cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE2]>;
6285f757f3fSDimitry Andricclass PDI<bits<8> o, Format F, dag outs, dag ins, string asm,
6295f757f3fSDimitry Andric          list<dag> pattern>
630cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
6315f757f3fSDimitry Andric        Requires<[UseSSE2]>;
6325f757f3fSDimitry Andricclass PDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
6335f757f3fSDimitry Andric            list<dag> pattern>
634cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
6355f757f3fSDimitry Andric        Requires<[UseSSE2]>;
6365f757f3fSDimitry Andricclass VSDI<bits<8> o, Format F, dag outs, dag ins, string asm,
6375f757f3fSDimitry Andric           list<dag> pattern>
638cb14a3feSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XD,
6395f757f3fSDimitry Andric        Requires<[UseAVX]>;
6405f757f3fSDimitry Andricclass VS2SI<bits<8> o, Format F, dag outs, dag ins, string asm,
6415f757f3fSDimitry Andric            list<dag> pattern>
642cb14a3feSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XS,
6435f757f3fSDimitry Andric        Requires<[HasAVX]>;
6445f757f3fSDimitry Andricclass VPDI<bits<8> o, Format F, dag outs, dag ins, string asm,
6455f757f3fSDimitry Andric           list<dag> pattern>
6465f757f3fSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern, SSEPackedDouble>,
647cb14a3feSDimitry Andric        TB, PD, Requires<[HasAVX]>;
6485f757f3fSDimitry Andricclass VS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
6495f757f3fSDimitry Andric           list<dag> pattern>
650cb14a3feSDimitry Andric      : I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, PD,
6515f757f3fSDimitry Andric        Requires<[UseAVX]>;
6525f757f3fSDimitry Andricclass S2I<bits<8> o, Format F, dag outs, dag ins, string asm,
6535f757f3fSDimitry Andric           list<dag> pattern>
654cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, PD, Requires<[UseSSE2]>;
6555f757f3fSDimitry Andricclass MMXSDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
6565f757f3fSDimitry Andric               list<dag> pattern>
657cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[HasMMX, HasSSE2]>;
6585f757f3fSDimitry Andricclass MMXS2SIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
6595f757f3fSDimitry Andric                list<dag> pattern>
660cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[HasMMX, HasSSE2]>;
6615f757f3fSDimitry Andric
6625f757f3fSDimitry Andric// SSE3 Instruction Templates:
6635f757f3fSDimitry Andric//
6645f757f3fSDimitry Andric//   S3I   - SSE3 instructions with PD prefixes.
6655f757f3fSDimitry Andric//   S3SI  - SSE3 instructions with XS prefix.
6665f757f3fSDimitry Andric//   S3DI  - SSE3 instructions with XD prefix.
6675f757f3fSDimitry Andric
6685f757f3fSDimitry Andricclass S3SI<bits<8> o, Format F, dag outs, dag ins, string asm,
6695f757f3fSDimitry Andric           list<dag> pattern>
670cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB, XS,
6715f757f3fSDimitry Andric        Requires<[UseSSE3]>;
6725f757f3fSDimitry Andricclass S3DI<bits<8> o, Format F, dag outs, dag ins, string asm,
6735f757f3fSDimitry Andric           list<dag> pattern>
674cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, XD,
6755f757f3fSDimitry Andric        Requires<[UseSSE3]>;
6765f757f3fSDimitry Andricclass S3I<bits<8> o, Format F, dag outs, dag ins, string asm,
6775f757f3fSDimitry Andric          list<dag> pattern>
678cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
6795f757f3fSDimitry Andric        Requires<[UseSSE3]>;
6805f757f3fSDimitry Andric
6815f757f3fSDimitry Andric
6825f757f3fSDimitry Andric// SSSE3 Instruction Templates:
6835f757f3fSDimitry Andric//
6845f757f3fSDimitry Andric//   SS38I - SSSE3 instructions with T8 prefix.
6855f757f3fSDimitry Andric//   SS3AI - SSSE3 instructions with TA prefix.
6865f757f3fSDimitry Andric//   MMXSS38I - SSSE3 instructions with T8 prefix and MMX operands.
6875f757f3fSDimitry Andric//   MMXSS3AI - SSSE3 instructions with TA prefix and MMX operands.
6885f757f3fSDimitry Andric//
6895f757f3fSDimitry Andric// Note: SSSE3 instructions have 64-bit and 128-bit versions. The 64-bit version
6905f757f3fSDimitry Andric// uses the MMX registers. The 64-bit versions are grouped with the MMX
6915f757f3fSDimitry Andric// classes. They need to be enabled even if AVX is enabled.
6925f757f3fSDimitry Andric
6935f757f3fSDimitry Andricclass SS38I<bits<8> o, Format F, dag outs, dag ins, string asm,
6945f757f3fSDimitry Andric            list<dag> pattern>
695cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
6965f757f3fSDimitry Andric        Requires<[UseSSSE3]>;
6975f757f3fSDimitry Andricclass SS3AI<bits<8> o, Format F, dag outs, dag ins, string asm,
6985f757f3fSDimitry Andric            list<dag> pattern>
699cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
7005f757f3fSDimitry Andric        Requires<[UseSSSE3]>;
7015f757f3fSDimitry Andricclass MMXSS38I<bits<8> o, Format F, dag outs, dag ins, string asm,
7025f757f3fSDimitry Andric               list<dag> pattern>
703cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8,
7045f757f3fSDimitry Andric        Requires<[HasMMX, HasSSSE3]>;
7055f757f3fSDimitry Andricclass MMXSS3AI<bits<8> o, Format F, dag outs, dag ins, string asm,
7065f757f3fSDimitry Andric               list<dag> pattern>
707cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA,
7085f757f3fSDimitry Andric        Requires<[HasMMX, HasSSSE3]>;
7095f757f3fSDimitry Andric
7105f757f3fSDimitry Andric// SSE4.1 Instruction Templates:
7115f757f3fSDimitry Andric//
7125f757f3fSDimitry Andric//   SS48I - SSE 4.1 instructions with T8 prefix.
7135f757f3fSDimitry Andric//   SS41AIi8 - SSE 4.1 instructions with TA prefix and ImmT == Imm8.
7145f757f3fSDimitry Andric//
7155f757f3fSDimitry Andricclass SS48I<bits<8> o, Format F, dag outs, dag ins, string asm,
7165f757f3fSDimitry Andric            list<dag> pattern>
717cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
7185f757f3fSDimitry Andric        Requires<[UseSSE41]>;
7195f757f3fSDimitry Andricclass SS4AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
7205f757f3fSDimitry Andric            list<dag> pattern>
721cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
7225f757f3fSDimitry Andric        Requires<[UseSSE41]>;
7235f757f3fSDimitry Andric
7245f757f3fSDimitry Andric// SSE4.2 Instruction Templates:
7255f757f3fSDimitry Andric//
7265f757f3fSDimitry Andric//   SS428I - SSE 4.2 instructions with T8 prefix.
7275f757f3fSDimitry Andricclass SS428I<bits<8> o, Format F, dag outs, dag ins, string asm,
7285f757f3fSDimitry Andric             list<dag> pattern>
729cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
7305f757f3fSDimitry Andric        Requires<[UseSSE42]>;
7315f757f3fSDimitry Andric
7325f757f3fSDimitry Andric//   SS42AI = SSE 4.2 instructions with TA prefix
7335f757f3fSDimitry Andricclass SS42AI<bits<8> o, Format F, dag outs, dag ins, string asm,
7345f757f3fSDimitry Andric             list<dag> pattern>
735cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
7365f757f3fSDimitry Andric        Requires<[UseSSE42]>;
7375f757f3fSDimitry Andric
7385f757f3fSDimitry Andric// AVX Instruction Templates:
7395f757f3fSDimitry Andric//   Instructions introduced in AVX (no SSE equivalent forms)
7405f757f3fSDimitry Andric//
741cb14a3feSDimitry Andric//   AVX8I - AVX instructions with T8, PD prefix.
742cb14a3feSDimitry Andric//   AVXAIi8 - AVX instructions with TA, PD prefix and ImmT = Imm8.
7435f757f3fSDimitry Andricclass AVX8I<bits<8> o, Format F, dag outs, dag ins, string asm,
7445f757f3fSDimitry Andric            list<dag> pattern>
745cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
7465f757f3fSDimitry Andric        Requires<[HasAVX]>;
7475f757f3fSDimitry Andricclass AVXAIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
7485f757f3fSDimitry Andric              list<dag> pattern>
749cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
7505f757f3fSDimitry Andric        Requires<[HasAVX]>;
7515f757f3fSDimitry Andric
7525f757f3fSDimitry Andric// AVX2 Instruction Templates:
7535f757f3fSDimitry Andric//   Instructions introduced in AVX2 (no SSE equivalent forms)
7545f757f3fSDimitry Andric//
755cb14a3feSDimitry Andric//   AVX28I - AVX2 instructions with T8, PD prefix.
756cb14a3feSDimitry Andric//   AVX2AIi8 - AVX2 instructions with TA, PD prefix and ImmT = Imm8.
7575f757f3fSDimitry Andricclass AVX28I<bits<8> o, Format F, dag outs, dag ins, string asm,
7585f757f3fSDimitry Andric            list<dag> pattern>
759cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
7605f757f3fSDimitry Andric        Requires<[HasAVX2]>;
7615f757f3fSDimitry Andricclass AVX2AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
7625f757f3fSDimitry Andric              list<dag> pattern>
763cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
7645f757f3fSDimitry Andric        Requires<[HasAVX2]>;
7655f757f3fSDimitry Andric
7665f757f3fSDimitry Andric
7675f757f3fSDimitry Andric// AVX-512 Instruction Templates:
7685f757f3fSDimitry Andric//   Instructions introduced in AVX-512 (no SSE equivalent forms)
7695f757f3fSDimitry Andric//
770cb14a3feSDimitry Andric//   AVX5128I - AVX-512 instructions with T8, PD prefix.
771cb14a3feSDimitry Andric//   AVX512AIi8 - AVX-512 instructions with TA, PD prefix and ImmT = Imm8.
7725f757f3fSDimitry Andric//   AVX512PDI  - AVX-512 instructions with PD, double packed.
7735f757f3fSDimitry Andric//   AVX512PSI  - AVX-512 instructions with PS, single packed.
7745f757f3fSDimitry Andric//   AVX512XS8I - AVX-512 instructions with T8 and XS prefixes.
7755f757f3fSDimitry Andric//   AVX512XSI  - AVX-512 instructions with XS prefix, generic domain.
7765f757f3fSDimitry Andric//   AVX512BI   - AVX-512 instructions with PD, int packed domain.
7775f757f3fSDimitry Andric//   AVX512SI   - AVX-512 scalar instructions with PD prefix.
7785f757f3fSDimitry Andric
7795f757f3fSDimitry Andricclass AVX5128I<bits<8> o, Format F, dag outs, dag ins, string asm,
7805f757f3fSDimitry Andric            list<dag> pattern>
781cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
7825f757f3fSDimitry Andric        Requires<[HasAVX512]>;
783cb14a3feSDimitry Andricclass AVX5128IBase : T8, PD {
7845f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedInt;
7855f757f3fSDimitry Andric}
7865f757f3fSDimitry Andricclass AVX512XS8I<bits<8> o, Format F, dag outs, dag ins, string asm,
7875f757f3fSDimitry Andric            list<dag> pattern>
788cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, XS,
7895f757f3fSDimitry Andric        Requires<[HasAVX512]>;
7905f757f3fSDimitry Andricclass AVX512XSI<bits<8> o, Format F, dag outs, dag ins, string asm,
7915f757f3fSDimitry Andric            list<dag> pattern>
792cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, XS,
7935f757f3fSDimitry Andric        Requires<[HasAVX512]>;
7945f757f3fSDimitry Andricclass AVX512XDI<bits<8> o, Format F, dag outs, dag ins, string asm,
7955f757f3fSDimitry Andric            list<dag> pattern>
796cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, XD,
7975f757f3fSDimitry Andric        Requires<[HasAVX512]>;
7985f757f3fSDimitry Andricclass AVX512BI<bits<8> o, Format F, dag outs, dag ins, string asm,
7995f757f3fSDimitry Andric            list<dag> pattern>
800cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, PD,
8015f757f3fSDimitry Andric        Requires<[HasAVX512]>;
802cb14a3feSDimitry Andricclass AVX512BIBase : TB, PD {
8035f757f3fSDimitry Andric  Domain ExeDomain = SSEPackedInt;
8045f757f3fSDimitry Andric}
8055f757f3fSDimitry Andricclass AVX512BIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
8065f757f3fSDimitry Andric              list<dag> pattern>
807cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, PD,
8085f757f3fSDimitry Andric        Requires<[HasAVX512]>;
8095f757f3fSDimitry Andricclass AVX512AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
8105f757f3fSDimitry Andric              list<dag> pattern>
811cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
8125f757f3fSDimitry Andric        Requires<[HasAVX512]>;
813cb14a3feSDimitry Andricclass AVX512AIi8Base : TA, PD {
8145f757f3fSDimitry Andric  ImmType ImmT = Imm8;
8155f757f3fSDimitry Andric}
8165f757f3fSDimitry Andricclass AVX512Ii8<bits<8> o, Format F, dag outs, dag ins, string asm,
8175f757f3fSDimitry Andric              list<dag> pattern>
8185f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>,
8195f757f3fSDimitry Andric        Requires<[HasAVX512]>;
8205f757f3fSDimitry Andricclass AVX512PDI<bits<8> o, Format F, dag outs, dag ins, string asm,
8215f757f3fSDimitry Andric           list<dag> pattern>
822cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
8235f757f3fSDimitry Andric        Requires<[HasAVX512]>;
8245f757f3fSDimitry Andricclass AVX512PSI<bits<8> o, Format F, dag outs, dag ins, string asm,
8255f757f3fSDimitry Andric           list<dag> pattern>
826cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
8275f757f3fSDimitry Andric        Requires<[HasAVX512]>;
8285f757f3fSDimitry Andricclass AVX512PIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
8295f757f3fSDimitry Andric              list<dag> pattern, Domain d>
8305f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, d>, Requires<[HasAVX512]>;
8315f757f3fSDimitry Andricclass AVX512PI<bits<8> o, Format F, dag outs, dag ins, string asm,
8325f757f3fSDimitry Andric              list<dag> pattern, Domain d>
8335f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, d>, Requires<[HasAVX512]>;
8345f757f3fSDimitry Andricclass AVX512FMA3S<bits<8> o, Format F, dag outs, dag ins, string asm,
8355f757f3fSDimitry Andric           list<dag>pattern>
836cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, T8, PD,
837cb14a3feSDimitry Andric        EVEX, VVVV, Requires<[HasAVX512]>;
8385f757f3fSDimitry Andric
8395f757f3fSDimitry Andricclass AVX512<bits<8> o, Format F, dag outs, dag ins, string asm,
8405f757f3fSDimitry Andric           list<dag>pattern>
8415f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, Requires<[HasAVX512]>;
8425f757f3fSDimitry Andric
8435f757f3fSDimitry Andric// AES Instruction Templates:
8445f757f3fSDimitry Andric//
8455f757f3fSDimitry Andric// AES8I
8465f757f3fSDimitry Andric// These use the same encoding as the SSE4.2 T8 and TA encodings.
8475f757f3fSDimitry Andricclass AES8I<bits<8> o, Format F, dag outs, dag ins, string asm,
8485f757f3fSDimitry Andric            list<dag>pattern>
849cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
8505f757f3fSDimitry Andric        Requires<[NoAVX, HasAES]>;
8515f757f3fSDimitry Andric
8525f757f3fSDimitry Andricclass AESAI<bits<8> o, Format F, dag outs, dag ins, string asm,
8535f757f3fSDimitry Andric            list<dag> pattern>
854cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
8555f757f3fSDimitry Andric        Requires<[NoAVX, HasAES]>;
8565f757f3fSDimitry Andric
8575f757f3fSDimitry Andric// PCLMUL Instruction Templates
8585f757f3fSDimitry Andricclass PCLMULIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
8595f757f3fSDimitry Andric               list<dag>pattern>
860cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD;
8615f757f3fSDimitry Andric
8625f757f3fSDimitry Andric// FMA3 Instruction Templates
8635f757f3fSDimitry Andricclass FMA3<bits<8> o, Format F, dag outs, dag ins, string asm,
8645f757f3fSDimitry Andric           list<dag>pattern>
865cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, T8, PD,
866cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoVLX]>;
8675f757f3fSDimitry Andricclass FMA3S<bits<8> o, Format F, dag outs, dag ins, string asm,
8685f757f3fSDimitry Andric            list<dag>pattern>
869cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, T8, PD,
870cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoAVX512]>;
8715f757f3fSDimitry Andricclass FMA3S_Int<bits<8> o, Format F, dag outs, dag ins, string asm,
8725f757f3fSDimitry Andric                list<dag>pattern>
873cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, T8, PD,
874cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA, NoAVX512]>;
8755f757f3fSDimitry Andric
8765f757f3fSDimitry Andric// FMA4 Instruction Templates
8775f757f3fSDimitry Andricclass FMA4<bits<8> o, Format F, dag outs, dag ins, string asm,
8785f757f3fSDimitry Andric           list<dag>pattern>
879cb14a3feSDimitry Andric      : Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
880cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA4, NoVLX]>;
8815f757f3fSDimitry Andricclass FMA4S<bits<8> o, Format F, dag outs, dag ins, string asm,
8825f757f3fSDimitry Andric            list<dag>pattern>
883cb14a3feSDimitry Andric      : Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
884cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA4, NoAVX512]>;
8855f757f3fSDimitry Andricclass FMA4S_Int<bits<8> o, Format F, dag outs, dag ins, string asm,
8865f757f3fSDimitry Andric                list<dag>pattern>
887cb14a3feSDimitry Andric      : Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
888cb14a3feSDimitry Andric        VEX, VVVV, FMASC, Requires<[HasFMA4]>;
8895f757f3fSDimitry Andric
8905f757f3fSDimitry Andric// XOP 2, 3 and 4 Operand Instruction Template
8915f757f3fSDimitry Andricclass IXOP<bits<8> o, Format F, dag outs, dag ins, string asm,
8925f757f3fSDimitry Andric           list<dag> pattern>
8935f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
8945f757f3fSDimitry Andric         XOP9, Requires<[HasXOP]>;
8955f757f3fSDimitry Andric
8965f757f3fSDimitry Andric// XOP 2 and 3 Operand Instruction Templates with imm byte
8975f757f3fSDimitry Andricclass IXOPi8<bits<8> o, Format F, dag outs, dag ins, string asm,
8985f757f3fSDimitry Andric           list<dag> pattern>
8995f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
9005f757f3fSDimitry Andric         XOP8, Requires<[HasXOP]>;
9015f757f3fSDimitry Andric// XOP 4 Operand Instruction Templates with imm byte
9025f757f3fSDimitry Andricclass IXOPi8Reg<bits<8> o, Format F, dag outs, dag ins, string asm,
9035f757f3fSDimitry Andric           list<dag> pattern>
9045f757f3fSDimitry Andric      : Ii8Reg<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
9055f757f3fSDimitry Andric         XOP8, Requires<[HasXOP]>;
9065f757f3fSDimitry Andric
9075f757f3fSDimitry Andric//  XOP 5 operand instruction (VEX encoding!)
9085f757f3fSDimitry Andricclass IXOP5<bits<8> o, Format F, dag outs, dag ins, string asm,
9095f757f3fSDimitry Andric           list<dag>pattern>
910cb14a3feSDimitry Andric      : Ii8Reg<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
911cb14a3feSDimitry Andric        VEX, VVVV, Requires<[HasXOP]>;
9125f757f3fSDimitry Andric
9135f757f3fSDimitry Andric// X86-64 Instruction templates...
9145f757f3fSDimitry Andric//
9155f757f3fSDimitry Andric
9165f757f3fSDimitry Andricclass RI<bits<8> o, Format F, dag outs, dag ins, string asm,
9175f757f3fSDimitry Andric         list<dag> pattern>
9185f757f3fSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, REX_W;
9195f757f3fSDimitry Andricclass RIi8 <bits<8> o, Format F, dag outs, dag ins, string asm,
9205f757f3fSDimitry Andric            list<dag> pattern>
9215f757f3fSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, REX_W;
9225f757f3fSDimitry Andricclass RIi16 <bits<8> o, Format F, dag outs, dag ins, string asm,
9235f757f3fSDimitry Andric            list<dag> pattern>
9245f757f3fSDimitry Andric      : Ii16<o, F, outs, ins, asm, pattern>, REX_W;
9255f757f3fSDimitry Andricclass RIi32 <bits<8> o, Format F, dag outs, dag ins, string asm,
9265f757f3fSDimitry Andric             list<dag> pattern>
9275f757f3fSDimitry Andric      : Ii32<o, F, outs, ins, asm, pattern>, REX_W;
9285f757f3fSDimitry Andricclass RIi32S <bits<8> o, Format F, dag outs, dag ins, string asm,
9295f757f3fSDimitry Andric              list<dag> pattern>
9305f757f3fSDimitry Andric      : Ii32S<o, F, outs, ins, asm, pattern>, REX_W;
9315f757f3fSDimitry Andricclass RIi64<bits<8> o, Format F, dag outs, dag ins, string asm,
9325f757f3fSDimitry Andric            list<dag> pattern>
9335f757f3fSDimitry Andric      : Ii64<o, F, outs, ins, asm, pattern>, REX_W;
9345f757f3fSDimitry Andric
9355f757f3fSDimitry Andricclass RS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
9365f757f3fSDimitry Andric           list<dag> pattern>
9375f757f3fSDimitry Andric      : S2I<o, F, outs, ins, asm, pattern>, REX_W;
9385f757f3fSDimitry Andricclass VRS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
9395f757f3fSDimitry Andric           list<dag> pattern>
9405f757f3fSDimitry Andric      : VS2I<o, F, outs, ins, asm, pattern>, REX_W;
9415f757f3fSDimitry Andric
9425f757f3fSDimitry Andric// MMX Instruction templates
9435f757f3fSDimitry Andric//
9445f757f3fSDimitry Andric// MMXI   - MMX instructions with TB prefix.
945cb14a3feSDimitry Andric// MMXRI  - MMX instructions with TB prefix and REX.W.
9465f757f3fSDimitry Andric// MMXIi8 - MMX instructions with ImmT == Imm8 and PS prefix.
9475f757f3fSDimitry Andricclass MMXI<bits<8> o, Format F, dag outs, dag ins, string asm,
9485f757f3fSDimitry Andric           list<dag> pattern>
949cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, Requires<[HasMMX]>;
9505f757f3fSDimitry Andricclass MMXRI<bits<8> o, Format F, dag outs, dag ins, string asm,
9515f757f3fSDimitry Andric            list<dag> pattern>
952cb14a3feSDimitry Andric      : I<o, F, outs, ins, asm, pattern>, TB, REX_W,
9535f757f3fSDimitry Andric        Requires<[HasMMX,In64BitMode]>;
9545f757f3fSDimitry Andricclass MMXIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
9555f757f3fSDimitry Andric             list<dag> pattern>
956cb14a3feSDimitry Andric      : Ii8<o, F, outs, ins, asm, pattern>, TB, Requires<[HasMMX]>;
9575f757f3fSDimitry Andric
9585f757f3fSDimitry Andric/// ITy - This instruction base class takes the type info for the instruction.
9595f757f3fSDimitry Andric/// Using this, it:
9605f757f3fSDimitry Andric/// 1. Concatenates together the instruction mnemonic with the appropriate
9615f757f3fSDimitry Andric///    suffix letter, a tab, and the arguments.
962cb14a3feSDimitry Andric/// 2. Infers whether the instruction should have a 0x40 REX_W prefix.
963cb14a3feSDimitry Andric/// 3. Infers whether the low bit of the opcode should be 0 (for i8 operations)
9645f757f3fSDimitry Andric///    or 1 (for i16,i32,i64 operations).
965647cbc5dSDimitry Andricclass ITy<bits<8> o, Format f, X86TypeInfo t, dag outs, dag ins, string m,
966647cbc5dSDimitry Andric          string args, list<dag> p>
967647cbc5dSDimitry Andric  : I<{o{7}, o{6}, o{5}, o{4}, o{3}, o{2}, o{1},
968647cbc5dSDimitry Andric       !if(!eq(t.HasEvenOpcode, 1), 0, o{0})}, f, outs, ins,
9697a6dacacSDimitry Andric      !strconcat(m, "{", t.InstrSuffix, "}\t", args), p>, NoCD8 {
970cb14a3feSDimitry Andric  let hasSideEffects = 0;
971647cbc5dSDimitry Andric  let hasREX_W  = t.HasREX_W;
972*0fca6ea1SDimitry Andric  let IgnoresW = !if(!eq(t.VT, i8), 1, 0);
9735f757f3fSDimitry Andric}
974cb14a3feSDimitry Andric
975647cbc5dSDimitry Andric// BinOpRR - Instructions that read "reg, reg".
976647cbc5dSDimitry Andricclass BinOpRR<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
977647cbc5dSDimitry Andric  : ITy<o, MRMDestReg, t, out, (ins t.RegClass:$src1, t.RegClass:$src2), m,
978647cbc5dSDimitry Andric        args, p>, Sched<[WriteALU]>;
979647cbc5dSDimitry Andric// BinOpRR_F - Instructions that read "reg, reg" and write EFLAGS only.
980647cbc5dSDimitry Andricclass BinOpRR_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
981647cbc5dSDimitry Andric  : BinOpRR<o, m, binop_args, t, (outs),
982647cbc5dSDimitry Andric            [(set EFLAGS, (node t.RegClass:$src1, t.RegClass:$src2))]>,
983647cbc5dSDimitry Andric    DefEFLAGS;
984647cbc5dSDimitry Andric// BinOpRR_F_Rev - Reversed encoding of BinOpRR_F
985647cbc5dSDimitry Andricclass BinOpRR_F_Rev<bits<8> o, string m, X86TypeInfo t>
986647cbc5dSDimitry Andric  : BinOpRR_F<o, m, t, null_frag>, DisassembleOnly {
987647cbc5dSDimitry Andric  let Form = MRMSrcReg;
988647cbc5dSDimitry Andric}
989647cbc5dSDimitry Andric// BinOpRR_R - Instructions that read "reg, reg" and write "reg".
990647cbc5dSDimitry Andricclass BinOpRR_R<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
991647cbc5dSDimitry Andric  : BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t,
992647cbc5dSDimitry Andric            (outs t.RegClass:$dst), []>, NDD<ndd>;
993647cbc5dSDimitry Andric// BinOpRR_R_Rev - Reversed encoding of BinOpRR_R
994647cbc5dSDimitry Andricclass BinOpRR_R_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
995647cbc5dSDimitry Andric  : BinOpRR_R<o, m, t, ndd>, DisassembleOnly {
996647cbc5dSDimitry Andric  let Form = MRMSrcReg;
997647cbc5dSDimitry Andric}
998647cbc5dSDimitry Andric// BinOpRR_RF - Instructions that read "reg, reg", and write "reg", EFLAGS.
999647cbc5dSDimitry Andricclass BinOpRR_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0>
1000647cbc5dSDimitry Andric  : BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t,
1001647cbc5dSDimitry Andric            (outs t.RegClass:$dst),
1002647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS,
1003647cbc5dSDimitry Andric             (node t.RegClass:$src1, t.RegClass:$src2))]>, DefEFLAGS, NDD<ndd>;
1004647cbc5dSDimitry Andric// BinOpRR_RF_Rev - Reversed encoding of BinOpRR_RF.
1005647cbc5dSDimitry Andricclass BinOpRR_RF_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
1006647cbc5dSDimitry Andric  : BinOpRR_RF<o, m, t, null_frag, ndd>, DisassembleOnly {
1007647cbc5dSDimitry Andric  let Form = MRMSrcReg;
1008647cbc5dSDimitry Andric}
1009647cbc5dSDimitry Andric// BinOpRRF_RF - Instructions that read "reg, reg", write "reg" and read/write
1010647cbc5dSDimitry Andric// EFLAGS.
10111db9f3b2SDimitry Andricclass BinOpRRF_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
1012647cbc5dSDimitry Andric  : BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
1013647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS,
1014647cbc5dSDimitry Andric             (node t.RegClass:$src1, t.RegClass:$src2,
1015647cbc5dSDimitry Andric             EFLAGS))]>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
1016647cbc5dSDimitry Andric  let SchedRW = [WriteADC];
1017647cbc5dSDimitry Andric}
1018647cbc5dSDimitry Andric// BinOpRRF_RF_Rev - Reversed encoding of BinOpRRF_RF
1019647cbc5dSDimitry Andricclass BinOpRRF_RF_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
1020647cbc5dSDimitry Andric  : BinOpRRF_RF<o, m, t, null_frag, ndd>, DisassembleOnly {
1021647cbc5dSDimitry Andric  let Form = MRMSrcReg;
1022647cbc5dSDimitry Andric}
1023647cbc5dSDimitry Andric
1024647cbc5dSDimitry Andric// BinOpRM - Instructions that read "reg, [mem]".
1025647cbc5dSDimitry Andricclass BinOpRM<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
1026647cbc5dSDimitry Andric  : ITy<o, MRMSrcMem, t, out, (ins t.RegClass:$src1, t.MemOperand:$src2), m,
1027647cbc5dSDimitry Andric        args, p>,
1028647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]> {
1029647cbc5dSDimitry Andric  let mayLoad = 1;
1030647cbc5dSDimitry Andric}
1031647cbc5dSDimitry Andric// BinOpRM_F - Instructions that read "reg, [mem]" and write EFLAGS only.
1032647cbc5dSDimitry Andricclass BinOpRM_F<bits<8> o, string m, X86TypeInfo t, SDNode node>
1033647cbc5dSDimitry Andric  : BinOpRM<o, m, binop_args, t, (outs),
1034647cbc5dSDimitry Andric            [(set EFLAGS, (node t.RegClass:$src1,
1035647cbc5dSDimitry Andric             (t.LoadNode addr:$src2)))]>, DefEFLAGS;
1036647cbc5dSDimitry Andric// BinOpRM_R - Instructions that read "reg, [mem]", and write "reg".
1037647cbc5dSDimitry Andricclass BinOpRM_R<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
1038647cbc5dSDimitry Andric  : BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
1039647cbc5dSDimitry Andric            []>, NDD<ndd>;
1040647cbc5dSDimitry Andric// BinOpRM_RF - Instructions that read "reg, [mem]", and write "reg", EFLAGS.
1041647cbc5dSDimitry Andricclass BinOpRM_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0>
1042647cbc5dSDimitry Andric  : BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
1043647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS, (node t.RegClass:$src1,
1044647cbc5dSDimitry Andric             (t.LoadNode addr:$src2)))]>, DefEFLAGS, NDD<ndd>;
1045647cbc5dSDimitry Andric// BinOpRMF_RF - Instructions that read "reg, [mem]", write "reg" and read/write
1046647cbc5dSDimitry Andric// EFLAGS.
10471db9f3b2SDimitry Andricclass BinOpRMF_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
1048647cbc5dSDimitry Andric  : BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
1049647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS,
1050647cbc5dSDimitry Andric             (node t.RegClass:$src1, (t.LoadNode addr:$src2), EFLAGS))]>,
1051647cbc5dSDimitry Andric    DefEFLAGS, UseEFLAGS, NDD<ndd> {
1052647cbc5dSDimitry Andric  let SchedRW = [WriteADC.Folded, WriteADC.ReadAfterFold,
1053647cbc5dSDimitry Andric                 // base, scale, index, offset, segment.
1054647cbc5dSDimitry Andric                 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1055647cbc5dSDimitry Andric                 // implicit register read.
1056647cbc5dSDimitry Andric                 WriteADC.ReadAfterFold];
1057647cbc5dSDimitry Andric}
1058647cbc5dSDimitry Andric
1059647cbc5dSDimitry Andric// BinOpRI - Instructions that read "reg, imm".
1060647cbc5dSDimitry Andricclass BinOpRI<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out, list<dag> p>
1061647cbc5dSDimitry Andric  : ITy<o, f, t, out, (ins t.RegClass:$src1, t.ImmOperand:$src2), m,
1062647cbc5dSDimitry Andric        args, p>, Sched<[WriteALU]> {
1063647cbc5dSDimitry Andric  let ImmT = t.ImmEncoding;
1064647cbc5dSDimitry Andric}
1065647cbc5dSDimitry Andric// BinOpRI_F - Instructions that read "reg, imm" and write EFLAGS only.
1066647cbc5dSDimitry Andricclass BinOpRI_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
1067647cbc5dSDimitry Andric                Format f>
1068647cbc5dSDimitry Andric  : BinOpRI<o, m, binop_args, t, f, (outs),
1069647cbc5dSDimitry Andric            [(set EFLAGS, (node t.RegClass:$src1,
1070647cbc5dSDimitry Andric             t.ImmOperator:$src2))]>, DefEFLAGS;
1071647cbc5dSDimitry Andric// BinOpRI_R - Instructions that read "reg, imm" and write "reg".
1072647cbc5dSDimitry Andricclass BinOpRI_R<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
1073647cbc5dSDimitry Andric  : BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
1074647cbc5dSDimitry Andric            []>, NDD<ndd>;
10757a6dacacSDimitry Andric// BinOpRI8U_R - Instructions that read "reg, u8imm" and write "reg".
10767a6dacacSDimitry Andricclass BinOpRI8U_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
10777a6dacacSDimitry Andric  : ITy<0xC1, f, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, u8imm:$src2), m,
10787a6dacacSDimitry Andric        !if(!eq(ndd, 0), binop_args, binop_ndd_args),
10797a6dacacSDimitry Andric        [(set t.RegClass:$dst, (node t.RegClass:$src1, (i8 imm:$src2)))]>, NDD<ndd> {
10807a6dacacSDimitry Andric  let ImmT = Imm8;
10817a6dacacSDimitry Andric}
1082647cbc5dSDimitry Andric// BinOpRI_RF - Instructions that read "reg, imm" and write "reg", EFLAGS.
1083647cbc5dSDimitry Andricclass BinOpRI_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, Format f, bit ndd = 0>
1084647cbc5dSDimitry Andric  : BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
1085647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS,
1086647cbc5dSDimitry Andric             (node t.RegClass:$src1, t.ImmOperator:$src2))]>, DefEFLAGS, NDD<ndd>;
1087647cbc5dSDimitry Andric// BinOpRIF_RF - Instructions that read "reg, imm", write "reg" and read/write
1088647cbc5dSDimitry Andric// EFLAGS.
1089647cbc5dSDimitry Andricclass BinOpRIF_RF<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f, bit ndd = 0>
1090647cbc5dSDimitry Andric  : BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
1091647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS,
1092647cbc5dSDimitry Andric             (node t.RegClass:$src1, t.ImmOperator:$src2,
1093647cbc5dSDimitry Andric             EFLAGS))]>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
1094647cbc5dSDimitry Andric  let SchedRW = [WriteADC];
1095647cbc5dSDimitry Andric}
1096647cbc5dSDimitry Andric// BinOpRI8 - Instructions that read "reg, imm8".
1097647cbc5dSDimitry Andricclass BinOpRI8<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out>
1098647cbc5dSDimitry Andric  : ITy<o, f, t, out, (ins t.RegClass:$src1, t.Imm8Operand:$src2), m,
1099647cbc5dSDimitry Andric        args, []>, Sched<[WriteALU]> {
1100647cbc5dSDimitry Andric  let ImmT = Imm8;
1101647cbc5dSDimitry Andric}
1102647cbc5dSDimitry Andric// BinOpRI8_F - Instructions that read "reg, imm8" and write EFLAGS only.
1103647cbc5dSDimitry Andricclass BinOpRI8_F<bits<8> o, string m, X86TypeInfo t, Format f>
1104647cbc5dSDimitry Andric  : BinOpRI8<o, m, binop_args, t, f, (outs)>, DefEFLAGS;
1105647cbc5dSDimitry Andric// BinOpRI8_R - Instructions that read "reg, imm8" and write "reg".
1106647cbc5dSDimitry Andricclass BinOpRI8_R<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
1107647cbc5dSDimitry Andric  : BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, NDD<ndd>;
1108647cbc5dSDimitry Andric// BinOpRI8_RF - Instructions that read "reg, imm8" and write "reg", EFLAGS.
1109647cbc5dSDimitry Andricclass BinOpRI8_RF<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
1110647cbc5dSDimitry Andric  : BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, DefEFLAGS, NDD<ndd>;
1111647cbc5dSDimitry Andric// BinOpRI8F_RF - Instructions that read "reg, imm", write "reg" and read/write
1112647cbc5dSDimitry Andric// EFLAGS.
1113647cbc5dSDimitry Andricclass BinOpRI8F_RF<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
1114647cbc5dSDimitry Andric  : BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
1115647cbc5dSDimitry Andric  let SchedRW = [WriteADC];
1116647cbc5dSDimitry Andric}
1117647cbc5dSDimitry Andric
1118647cbc5dSDimitry Andric// BinOpMR - Instructions that read "[mem], reg".
1119647cbc5dSDimitry Andricclass BinOpMR<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
1120647cbc5dSDimitry Andric  : ITy<o, MRMDestMem, t, out, (ins t.MemOperand:$src1, t.RegClass:$src2), m,
1121647cbc5dSDimitry Andric        args, p> {
1122647cbc5dSDimitry Andric  let mayLoad = 1;
1123647cbc5dSDimitry Andric  let SchedRW = [WriteALU.Folded, WriteALU.ReadAfterFold];
1124647cbc5dSDimitry Andric}
1125647cbc5dSDimitry Andric// BinOpMR_R - Instructions that read "[mem], reg", and write "reg".
1126647cbc5dSDimitry Andricclass BinOpMR_R<bits<8> o, string m, X86TypeInfo t>
1127647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst), []>, NDD<1>;
1128647cbc5dSDimitry Andric// BinOpMR_RF - Instructions that read "[mem], reg", and write "reg", EFLAGS.
1129647cbc5dSDimitry Andricclass BinOpMR_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
1130647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
1131647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1),
1132647cbc5dSDimitry Andric             t.RegClass:$src2))]>, DefEFLAGS, NDD<1>;
1133647cbc5dSDimitry Andric// BinOpMR_F - Instructions that read "[mem], imm8" and write EFLAGS only.
1134647cbc5dSDimitry Andricclass BinOpMR_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
1135647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_args, t, (outs),
1136647cbc5dSDimitry Andric            [(set EFLAGS, (node (t.LoadNode addr:$src1), t.RegClass:$src2))]>,
1137647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault,
1138647cbc5dSDimitry Andric            ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>, DefEFLAGS;
1139647cbc5dSDimitry Andric// BinOpMR_M - Instructions that read "[mem], reg" and write "[mem]".
1140647cbc5dSDimitry Andricclass BinOpMR_M<bits<8> o, string m, X86TypeInfo t>
1141647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_args, t, (outs), []>,
1142647cbc5dSDimitry Andric    Sched<[WriteALURMW,
1143647cbc5dSDimitry Andric           // base, scale, index, offset, segment
1144647cbc5dSDimitry Andric           ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault]> {
1145647cbc5dSDimitry Andric  let mayStore = 1;
1146647cbc5dSDimitry Andric}
1147647cbc5dSDimitry Andric// BinOpMR_MF - Instructions that read "[mem], reg" and write "[mem]", EFLAGS.
1148647cbc5dSDimitry Andricclass BinOpMR_MF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
1149647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_args, t, (outs),
1150647cbc5dSDimitry Andric            [(store (node (load addr:$src1), t.RegClass:$src2), addr:$src1),
1151647cbc5dSDimitry Andric             (implicit EFLAGS)]>,
1152647cbc5dSDimitry Andric    Sched<[WriteALURMW,
1153647cbc5dSDimitry Andric           // base, scale, index, offset, segment
1154647cbc5dSDimitry Andric           ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1155647cbc5dSDimitry Andric           WriteALU.ReadAfterFold]>, // reg
1156647cbc5dSDimitry Andric    DefEFLAGS {
1157647cbc5dSDimitry Andric  let mayStore = 1;
1158647cbc5dSDimitry Andric}
1159647cbc5dSDimitry Andric// BinOpMRF_RF - Instructions that read "[mem], reg", write "reg" and
1160647cbc5dSDimitry Andric// read/write EFLAGS.
1161647cbc5dSDimitry Andricclass BinOpMRF_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
1162647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
1163647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS, (node (load addr:$src1),
1164647cbc5dSDimitry Andric             t.RegClass:$src2, EFLAGS))]>, DefEFLAGS, UseEFLAGS, NDD<1>,
1165647cbc5dSDimitry Andric    Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>;
1166647cbc5dSDimitry Andric// BinOpMRF_MF - Instructions that read "[mem], reg", write "[mem]" and
1167647cbc5dSDimitry Andric// read/write EFLAGS.
1168647cbc5dSDimitry Andricclass BinOpMRF_MF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
1169647cbc5dSDimitry Andric  : BinOpMR<o, m, binop_args, t, (outs),
1170647cbc5dSDimitry Andric            [(store (node (load addr:$src1), t.RegClass:$src2, EFLAGS),
1171647cbc5dSDimitry Andric             addr:$src1), (implicit EFLAGS)]>,
1172647cbc5dSDimitry Andric    Sched<[WriteADCRMW,
1173647cbc5dSDimitry Andric          // base, scale, index, offset, segment
1174647cbc5dSDimitry Andric          ReadDefault, ReadDefault, ReadDefault,
1175647cbc5dSDimitry Andric          ReadDefault, ReadDefault,
1176647cbc5dSDimitry Andric          WriteALU.ReadAfterFold,    // reg
1177647cbc5dSDimitry Andric          WriteALU.ReadAfterFold]>,  // EFLAGS
1178647cbc5dSDimitry Andric    DefEFLAGS, UseEFLAGS {
1179647cbc5dSDimitry Andric  let mayStore = 1;
1180647cbc5dSDimitry Andric}
1181647cbc5dSDimitry Andric
1182647cbc5dSDimitry Andric// BinOpMI - Instructions that read "[mem], imm".
1183647cbc5dSDimitry Andricclass BinOpMI<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out, list<dag> p>
1184647cbc5dSDimitry Andric  : ITy<o, f, t, out, (ins t.MemOperand:$src1, t.ImmOperand:$src2), m,
1185647cbc5dSDimitry Andric        args, p> {
1186647cbc5dSDimitry Andric  let ImmT = t.ImmEncoding;
1187647cbc5dSDimitry Andric  let mayLoad = 1;
1188647cbc5dSDimitry Andric}
1189647cbc5dSDimitry Andric// BinOpMI_F - Instructions that read "[mem], imm" and write EFLAGS only.
1190647cbc5dSDimitry Andricclass BinOpMI_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
1191647cbc5dSDimitry Andric                Format f>
1192647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_args, t, f, (outs),
1193647cbc5dSDimitry Andric            [(set EFLAGS, (node (t.LoadNode addr:$src1), t.ImmOperator:$src2))]>,
1194647cbc5dSDimitry Andric    Sched<[WriteALU.Folded]>, DefEFLAGS;
1195647cbc5dSDimitry Andric// BinOpMI_R - Instructions that read "[mem], imm" and write "reg".
1196647cbc5dSDimitry Andricclass BinOpMI_R<bits<8> o, string m, X86TypeInfo t, Format f>
1197647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst), []>,
1198647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
1199647cbc5dSDimitry Andric// BinOpMI_R - Instructions that read "[mem], imm" and write "reg", EFLAGS.
1200647cbc5dSDimitry Andricclass BinOpMI_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
1201647cbc5dSDimitry Andric                Format f>
1202647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
1203647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1), t.ImmOperator:$src2))]>,
1204647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
1205647cbc5dSDimitry Andric// BinOpMI_M - Instructions that read "[mem], imm" and write "[mem]".
1206647cbc5dSDimitry Andricclass BinOpMI_M<bits<8> o, string m, X86TypeInfo t, Format f>
1207647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_args, t, f, (outs), []>, Sched<[WriteALURMW]> {
1208647cbc5dSDimitry Andric  let mayStore = 1;
1209647cbc5dSDimitry Andric}
1210647cbc5dSDimitry Andric// BinOpMI_MF - Instructions that read "[mem], imm" and write "[mem]", EFLAGS.
1211647cbc5dSDimitry Andricclass BinOpMI_MF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, Format f>
1212647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_args, t, f, (outs),
1213647cbc5dSDimitry Andric            [(store (node (t.VT (load addr:$src1)),
1214647cbc5dSDimitry Andric             t.ImmOperator:$src2), addr:$src1), (implicit EFLAGS)]>,
1215647cbc5dSDimitry Andric    Sched<[WriteALURMW]>, DefEFLAGS {
1216647cbc5dSDimitry Andric  let mayStore = 1;
1217647cbc5dSDimitry Andric}
1218647cbc5dSDimitry Andric// BinOpMIF_RF - Instructions that read "[mem], imm", write "reg" and
1219647cbc5dSDimitry Andric// read/write EFLAGS.
1220647cbc5dSDimitry Andricclass BinOpMIF_RF<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f>
1221647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
1222647cbc5dSDimitry Andric            [(set t.RegClass:$dst, EFLAGS, (node (t.VT (load addr:$src1)),
1223647cbc5dSDimitry Andric             t.ImmOperator:$src2, EFLAGS))]>,
1224647cbc5dSDimitry Andric    Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>, DefEFLAGS, UseEFLAGS, NDD<1>;
1225647cbc5dSDimitry Andric// BinOpMIF_MF - Instructions that read "[mem], imm", write "[mem]" and
1226647cbc5dSDimitry Andric// read/write EFLAGS.
1227647cbc5dSDimitry Andricclass BinOpMIF_MF<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f>
1228647cbc5dSDimitry Andric  : BinOpMI<o, m, binop_args, t, f, (outs),
1229647cbc5dSDimitry Andric            [(store (node (t.VT (load addr:$src1)),
1230647cbc5dSDimitry Andric             t.ImmOperator:$src2, EFLAGS), addr:$src1), (implicit EFLAGS)]>,
1231647cbc5dSDimitry Andric    Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS {
1232647cbc5dSDimitry Andric  let mayStore = 1;
1233647cbc5dSDimitry Andric}
1234647cbc5dSDimitry Andric
1235647cbc5dSDimitry Andric// BinOpMI8 - Instructions that read "[mem], imm8".
1236647cbc5dSDimitry Andricclass BinOpMI8<string m, string args, X86TypeInfo t, Format f, dag out>
1237647cbc5dSDimitry Andric  : ITy<0x83, f, t, out, (ins t.MemOperand:$src1, t.Imm8Operand:$src2), m,
1238647cbc5dSDimitry Andric        args, []> {
1239647cbc5dSDimitry Andric  let ImmT = Imm8;
1240647cbc5dSDimitry Andric  let mayLoad = 1;
1241647cbc5dSDimitry Andric}
12427a6dacacSDimitry Andric// BinOpMI8U - Instructions that read "[mem], u8imm".
12437a6dacacSDimitry Andricclass BinOpMI8U<string m, string args, X86TypeInfo t, Format f, dag out, list<dag> p>
12447a6dacacSDimitry Andric  : ITy<0xC1, f, t, out, (ins t.MemOperand:$src1, u8imm:$src2), m, args, p> {
12457a6dacacSDimitry Andric  let ImmT = Imm8;
12467a6dacacSDimitry Andric  let mayLoad = 1;
12477a6dacacSDimitry Andric}
1248647cbc5dSDimitry Andric// BinOpMI8_F - Instructions that read "[mem], imm8" and write EFLAGS only.
1249647cbc5dSDimitry Andricclass BinOpMI8_F<string m, X86TypeInfo t, Format f>
1250647cbc5dSDimitry Andric  : BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALU.Folded]>, DefEFLAGS;
1251647cbc5dSDimitry Andric// BinOpMI8_R - Instructions that read "[mem], imm8" and write "reg".
1252647cbc5dSDimitry Andricclass BinOpMI8_R<string m, X86TypeInfo t, Format f>
1253647cbc5dSDimitry Andric  : BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
12547a6dacacSDimitry Andric// BinOpMI8U_R - Instructions that read "[mem], u8imm" and write "reg".
12557a6dacacSDimitry Andricclass BinOpMI8U_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
12567a6dacacSDimitry Andric  : BinOpMI8U<m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
12577a6dacacSDimitry Andric              [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), (i8 imm:$src2)))]>, NDD<1>;
1258647cbc5dSDimitry Andric// BinOpMI8_RF - Instructions that read "[mem], imm8" and write "reg"/EFLAGS.
1259647cbc5dSDimitry Andricclass BinOpMI8_RF<string m, X86TypeInfo t, Format f>
1260647cbc5dSDimitry Andric  : BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
1261647cbc5dSDimitry Andric// BinOpMI8_M - Instructions that read "[mem], imm8" and write "[mem]".
1262647cbc5dSDimitry Andricclass BinOpMI8_M<string m, X86TypeInfo t, Format f>
1263647cbc5dSDimitry Andric  : BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALURMW]> {
1264647cbc5dSDimitry Andric  let mayStore = 1;
1265647cbc5dSDimitry Andric}
12667a6dacacSDimitry Andric// BinOpMI8U_M - Instructions that read "[mem], u8imm" and write "[mem]".
12677a6dacacSDimitry Andricclass BinOpMI8U_M<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
12687a6dacacSDimitry Andric  : BinOpMI8U<m, binop_args, t, f, (outs),
12697a6dacacSDimitry Andric              [(store (node (t.LoadNode addr:$src1), (i8 imm:$src2)), addr:$src1)]> {
12707a6dacacSDimitry Andric  let mayStore = 1;
12717a6dacacSDimitry Andric}
1272647cbc5dSDimitry Andric// BinOpMI8_MF - Instructions that read "[mem], imm8" and write "[mem]", EFLAGS.
1273647cbc5dSDimitry Andricclass BinOpMI8_MF<string m, X86TypeInfo t, Format f>
1274647cbc5dSDimitry Andric  : BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALURMW]>, DefEFLAGS {
1275647cbc5dSDimitry Andric  let mayStore = 1;
1276647cbc5dSDimitry Andric}
1277647cbc5dSDimitry Andric// BinOpMI8F_RF - Instructions that read "[mem], imm8", write "reg" and
1278647cbc5dSDimitry Andric// read/write EFLAGS.
1279647cbc5dSDimitry Andricclass BinOpMI8F_RF<string m, X86TypeInfo t, Format f>
1280647cbc5dSDimitry Andric  : BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>,
1281647cbc5dSDimitry Andric    Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>, DefEFLAGS, UseEFLAGS, NDD<1>;
1282647cbc5dSDimitry Andric// BinOpMI8F_MF - Instructions that read "[mem], imm8", write "[mem]" and
1283647cbc5dSDimitry Andric// read/write EFLAGS.
1284647cbc5dSDimitry Andricclass BinOpMI8F_MF<string m, X86TypeInfo t, Format f>
1285647cbc5dSDimitry Andric  : BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS {
1286647cbc5dSDimitry Andric  let mayStore = 1;
1287647cbc5dSDimitry Andric}
1288647cbc5dSDimitry Andric
1289647cbc5dSDimitry Andric// BinOpAI - Instructions that read "a-reg imm" (Accumulator register).
1290647cbc5dSDimitry Andricclass BinOpAI<bits<8> o, string m, X86TypeInfo t, Register areg, string args>
1291647cbc5dSDimitry Andric  : ITy<o, RawFrm, t, (outs), (ins t.ImmOperand:$src), m, args, []>,
1292647cbc5dSDimitry Andric    Sched<[WriteALU]> {
1293647cbc5dSDimitry Andric  let ImmT = t.ImmEncoding;
1294647cbc5dSDimitry Andric  let Uses = [areg];
1295647cbc5dSDimitry Andric}
1296647cbc5dSDimitry Andric// BinOpAI_F - Instructions that read "a-reg imm" and write EFLAGS only.
1297647cbc5dSDimitry Andricclass BinOpAI_F<bits<8> o, string m, X86TypeInfo t, Register areg, string args>
1298647cbc5dSDimitry Andric  : BinOpAI<o, m, t, areg, args>, DefEFLAGS;
1299647cbc5dSDimitry Andric
1300647cbc5dSDimitry Andric// BinOpAI_AF - Instructions that read "a-reg imm" and write a-reg/EFLAGS.
1301647cbc5dSDimitry Andricclass BinOpAI_AF<bits<8> o, string m, X86TypeInfo t, Register areg,
1302647cbc5dSDimitry Andric                 string args> : BinOpAI<o, m, t, areg, args> {
1303647cbc5dSDimitry Andric  let Defs = [areg, EFLAGS];
1304647cbc5dSDimitry Andric}
1305647cbc5dSDimitry Andric// BinOpAIF_AF - Instructions that read "a-reg imm", write a-reg and read/write
1306647cbc5dSDimitry Andric// EFLAGS.
1307647cbc5dSDimitry Andricclass BinOpAIF_AF<bits<8> o, string m, X86TypeInfo t, Register areg,
1308647cbc5dSDimitry Andric                  string args> : BinOpAI<o, m, t, areg, args> {
1309647cbc5dSDimitry Andric  let Uses = [areg, EFLAGS];
1310647cbc5dSDimitry Andric  let Defs = [areg, EFLAGS];
1311647cbc5dSDimitry Andric  let SchedRW = [WriteADC];
1312647cbc5dSDimitry Andric}
13137a6dacacSDimitry Andric// BinOpRC_R - Instructions that read "reg, cl" and write reg.
13147a6dacacSDimitry Andricclass BinOpRC_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
13157a6dacacSDimitry Andric  : ITy<0xD3, f, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1), m,
13167a6dacacSDimitry Andric        !if(!eq(ndd, 0), binop_cl_args, binop_cl_ndd_args),
13177a6dacacSDimitry Andric        [(set t.RegClass:$dst, (node t.RegClass:$src1, CL))]>, NDD<ndd> {
13187a6dacacSDimitry Andric  let Uses = [CL];
13197a6dacacSDimitry Andric}
13207a6dacacSDimitry Andric// BinOpMC_M - Instructions that read "[mem], cl" and write [mem].
13217a6dacacSDimitry Andricclass BinOpMC_M<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
13227a6dacacSDimitry Andric  : ITy<0xD3, f, t, (outs), (ins t.MemOperand:$src1), m, binop_cl_args,
13237a6dacacSDimitry Andric        [(store (node (t.LoadNode addr:$src1), CL), addr:$src1)]> {
13247a6dacacSDimitry Andric  let Uses = [CL];
13257a6dacacSDimitry Andric  let mayLoad = 1;
13267a6dacacSDimitry Andric  let mayStore = 1;
13277a6dacacSDimitry Andric}
13287a6dacacSDimitry Andric// BinOpMC_R - Instructions that read "[mem], cl" and write reg.
13297a6dacacSDimitry Andricclass BinOpMC_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
13307a6dacacSDimitry Andric  : ITy<0xD3, f, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1), m, binop_cl_ndd_args,
13317a6dacacSDimitry Andric        [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), CL))]>, NDD<1> {
13327a6dacacSDimitry Andric  let Uses = [CL];
13337a6dacacSDimitry Andric  let mayLoad = 1;
13347a6dacacSDimitry Andric}
1335647cbc5dSDimitry Andric
1336647cbc5dSDimitry Andric// UnaryOpR - Instructions that read "reg".
1337647cbc5dSDimitry Andricclass UnaryOpR<bits<8> o, Format f, string m, string args, X86TypeInfo t,
1338647cbc5dSDimitry Andric               dag out, list<dag> p>
1339647cbc5dSDimitry Andric  : ITy<o, f, t, out, (ins t.RegClass:$src1), m, args, p>, Sched<[WriteALU]>;
1340647cbc5dSDimitry Andric// UnaryOpR_R - Instructions that read "reg" and write "reg".
1341647cbc5dSDimitry Andricclass UnaryOpR_R<bits<8> o, Format f, string m, X86TypeInfo t,
13427a6dacacSDimitry Andric                  SDPatternOperator node = null_frag, bit ndd = 0>
1343647cbc5dSDimitry Andric  : UnaryOpR<o, f, m, !if(!eq(ndd, 0), unaryop_args, unaryop_ndd_args), t,
1344647cbc5dSDimitry Andric             (outs t.RegClass:$dst),
1345647cbc5dSDimitry Andric             [(set t.RegClass:$dst, (node t.RegClass:$src1))]>, NDD<ndd>;
1346647cbc5dSDimitry Andric// UnaryOpR_RF - Instructions that read "reg" and write "reg"/EFLAGS.
1347647cbc5dSDimitry Andricclass UnaryOpR_RF<bits<8> o, Format f, string m, X86TypeInfo t,
13487a6dacacSDimitry Andric                  SDPatternOperator node = null_frag, bit ndd = 0>
1349647cbc5dSDimitry Andric  : UnaryOpR<o, f, m, !if(!eq(ndd, 0), unaryop_args, unaryop_ndd_args), t,
1350647cbc5dSDimitry Andric             (outs t.RegClass:$dst),
1351647cbc5dSDimitry Andric             [(set t.RegClass:$dst, (node t.RegClass:$src1)),
1352647cbc5dSDimitry Andric              (implicit EFLAGS)]>, DefEFLAGS, NDD<ndd>;
1353647cbc5dSDimitry Andric
1354647cbc5dSDimitry Andric// UnaryOpM - Instructions that read "[mem]".
1355647cbc5dSDimitry Andricclass UnaryOpM<bits<8> o, Format f, string m, string args, X86TypeInfo t,
1356647cbc5dSDimitry Andric               dag out, list<dag> p>
1357647cbc5dSDimitry Andric  : ITy<o, f, t, out, (ins t.MemOperand:$src1), m, args, p> {
1358647cbc5dSDimitry Andric  let mayLoad = 1;
1359647cbc5dSDimitry Andric}
1360647cbc5dSDimitry Andric// UnaryOpM_R - Instructions that read "[mem]" and writes "reg".
1361647cbc5dSDimitry Andricclass UnaryOpM_R<bits<8> o, Format f, string m, X86TypeInfo t,
13627a6dacacSDimitry Andric                  SDPatternOperator node = null_frag>
1363647cbc5dSDimitry Andric  : UnaryOpM<o, f, m, unaryop_ndd_args, t, (outs t.RegClass:$dst),
1364647cbc5dSDimitry Andric             [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1)))]>,
1365647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
1366647cbc5dSDimitry Andric// UnaryOpM_RF - Instructions that read "[mem]" and writes "reg"/EFLAGS.
1367647cbc5dSDimitry Andricclass UnaryOpM_RF<bits<8> o, Format f, string m, X86TypeInfo t,
13687a6dacacSDimitry Andric                  SDPatternOperator node = null_frag>
1369647cbc5dSDimitry Andric  : UnaryOpM<o, f, m, unaryop_ndd_args, t, (outs t.RegClass:$dst),
1370647cbc5dSDimitry Andric             [(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1)))]>,
1371647cbc5dSDimitry Andric    Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
1372647cbc5dSDimitry Andric// UnaryOpM_M - Instructions that read "[mem]" and writes "[mem]".
1373647cbc5dSDimitry Andricclass UnaryOpM_M<bits<8> o, Format f, string m, X86TypeInfo t,
13747a6dacacSDimitry Andric                  SDPatternOperator node = null_frag>
1375647cbc5dSDimitry Andric  : UnaryOpM<o, f, m, unaryop_args, t, (outs),
1376647cbc5dSDimitry Andric             [(store (node (t.LoadNode addr:$src1)), addr:$src1)]>,
1377647cbc5dSDimitry Andric    Sched<[WriteALURMW]>{
1378647cbc5dSDimitry Andric  let mayStore = 1;
1379647cbc5dSDimitry Andric}
1380647cbc5dSDimitry Andric// UnaryOpM_MF - Instructions that read "[mem]" and writes "[mem]"/EFLAGS.
1381647cbc5dSDimitry Andricclass UnaryOpM_MF<bits<8> o, Format f, string m, X86TypeInfo t,
13827a6dacacSDimitry Andric                  SDPatternOperator node = null_frag>
1383647cbc5dSDimitry Andric  : UnaryOpM<o, f, m, unaryop_args, t, (outs),
1384647cbc5dSDimitry Andric             [(store (node (t.LoadNode addr:$src1)), addr:$src1),
1385647cbc5dSDimitry Andric              (implicit EFLAGS)]>, Sched<[WriteALURMW]>, DefEFLAGS {
1386647cbc5dSDimitry Andric  let mayStore = 1;
1387647cbc5dSDimitry Andric}
1388