//===-- X86InstrUtils.td - X86 Instruction Utilities --------*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file provides utilities for simplifying the instruction definitions. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Classes for setting the fields of X86Inst //===----------------------------------------------------------------------===// // Prefix byte classes which are used to indicate to the ad-hoc machine code // emitter that various prefix bytes are required. class OpSize16 { OperandSize OpSize = OpSize16; } class OpSize32 { OperandSize OpSize = OpSize32; } class AdSize16 { AddressSize AdSize = AdSize16; } class AdSize32 { AddressSize AdSize = AdSize32; } class AdSize64 { AddressSize AdSize = AdSize64; } class REX_W { bit hasREX_W = 1; } class LOCK { bit hasLockPrefix = 1; } class REP { bit hasREPPrefix = 1; } class TB { Map OpMap = TB; } class T8 { Map OpMap = T8; } class TA { Map OpMap = TA; } class T_MAP4 { Map OpMap = T_MAP4; } class T_MAP5 { Map OpMap = T_MAP5; } class T_MAP6 { Map OpMap = T_MAP6; } class T_MAP7 { Map OpMap = T_MAP7; } class XOP8 { Map OpMap = XOP8; } class XOP9 { Map OpMap = XOP9; } class XOPA { Map OpMap = XOPA; } class ThreeDNow { Map OpMap = ThreeDNow; } class PS { Prefix OpPrefix = PS; } class PD { Prefix OpPrefix = PD; } class XD { Prefix OpPrefix = XD; } class XS { Prefix OpPrefix = XS; } class XOP { Encoding OpEnc = EncXOP; } class VEX { Encoding OpEnc = EncVEX; } class EVEX { Encoding OpEnc = EncEVEX; } class WIG { bit IgnoresW = 1; } class VEX_L { bit hasVEX_L = 1; } class VEX_LIG { bit ignoresVEX_L = 1; } class VVVV { bit hasVEX_4V = 1; } class EVEX_K { bit hasEVEX_K = 1; } class EVEX_KZ : EVEX_K { bit hasEVEX_Z = 1; } class EVEX_B { bit hasEVEX_B = 1; } class EVEX_NF { bit hasEVEX_NF = 1; } class EVEX_RC { bit hasEVEX_RC = 1; } class EVEX_V512 { bit hasEVEX_L2 = 1; bit hasVEX_L = 0; } class EVEX_V256 { bit hasEVEX_L2 = 0; bit hasVEX_L = 1; } class EVEX_V128 { bit hasEVEX_L2 = 0; bit hasVEX_L = 0; } class NOTRACK { bit hasNoTrackPrefix = 1; } class SIMD_EXC { list Uses = [MXCSR]; bit mayRaiseFPException = 1; } // Specify AVX512 8-bit compressed displacement encoding based on the vector // element size in bits (8, 16, 32, 64) and the CDisp8 form. class EVEX_CD8 { int CD8_EltSize = !srl(esize, 3); bits<3> CD8_Form = form.Value; } class NoCD8 { bits<7> CD8_Scale = 0; } class AVX512BIi8Base : TB, PD { Domain ExeDomain = SSEPackedInt; ImmType ImmT = Imm8; } class AVX512XSIi8Base : TB, XS { Domain ExeDomain = SSEPackedInt; ImmType ImmT = Imm8; } class AVX512XDIi8Base : TB, XD { Domain ExeDomain = SSEPackedInt; ImmType ImmT = Imm8; } class AVX512PSIi8Base : TB { Domain ExeDomain = SSEPackedSingle; ImmType ImmT = Imm8; } class AVX512PDIi8Base : TB, PD { Domain ExeDomain = SSEPackedDouble; ImmType ImmT = Imm8; } class ExplicitREX2Prefix { ExplicitOpPrefix explicitOpPrefix = ExplicitREX2; } class ExplicitVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitVEX; } class ExplicitEVEXPrefix { ExplicitOpPrefix explicitOpPrefix = ExplicitEVEX; } class DefEFLAGS { list Defs = [EFLAGS]; } class UseEFLAGS { list Uses = [EFLAGS]; } class DisassembleOnly { // The disassembler should know about this, but not the asmparser. bit isCodeGenOnly = 1; bit ForceDisassemble = 1; } defvar unaryop_args = "$src1"; defvar unaryop_ndd_args = "{$src1, $dst|$dst, $src1}"; defvar binop_args = "{$src2, $src1|$src1, $src2}"; defvar binop_ndd_args = "{$src2, $src1, $dst|$dst, $src1, $src2}"; defvar binop_cl_args = "{%cl, $src1|$src1, cl}"; defvar binop_cl_ndd_args = "{%cl, $src1, $dst|$dst, $src1, cl}"; defvar triop_args = "{$src3, $src2, $src1|$src1, $src2, $src3}"; defvar triop_ndd_args = "{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"; defvar triop_cl_args = "{%cl, $src2, $src1|$src1, $src2, cl}"; defvar triop_cl_ndd_args = "{%cl, $src2, $src1, $dst|$dst, $src1, $src2, cl}"; defvar tie_dst_src1 = "$src1 = $dst"; // NDD - Helper for new data destination instructions class NDD { string Constraints = !if(!eq(ndd, 0), tie_dst_src1, ""); Encoding OpEnc = !if(!eq(ndd, 0), EncNormal, EncEVEX); bit hasEVEX_B = ndd; bit hasVEX_4V = ndd; Map OpMap = !if(!eq(ndd, 0), OB, T_MAP4); } // NF - Helper for NF (no flags update) instructions class NF: T_MAP4, EVEX, EVEX_NF; // PL - Helper for promoted legacy instructions class PL: T_MAP4, EVEX, ExplicitEVEXPrefix; // ZU - Helper for Zero Upper instructions class ZU: T_MAP4, EVEX, EVEX_B; //===----------------------------------------------------------------------===// // X86 Type infomation definitions //===----------------------------------------------------------------------===// /// X86TypeInfo - This is a bunch of information that describes relevant X86 /// information about value types. For example, it can tell you what the /// register class and preferred load to use. class X86TypeInfo { /// VT - This is the value type itself. ValueType VT = vt; /// InstrSuffix - This is the suffix used on instructions with this type. For /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q". string InstrSuffix = instrsuffix; /// RegClass - This is the register class associated with this type. For /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64. RegisterClass RegClass = regclass; /// LoadNode - This is the load node associated with this type. For /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64. PatFrag LoadNode = loadnode; /// MemOperand - This is the memory operand associated with this type. For /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem. X86MemOperand MemOperand = memoperand; /// ImmEncoding - This is the encoding of an immediate of this type. For /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32. Note that i64 -> Imm32 /// since the immediate fields of i64 instructions is a 32-bit sign extended /// value. ImmType ImmEncoding = immkind; /// ImmOperand - This is the operand kind of an immediate of this type. For /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm. Note that i64 -> /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign /// extended value. Operand ImmOperand = immoperand; /// ImmOperator - This is the operator that should be used to match an /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32). SDPatternOperator ImmOperator = immoperator; SDPatternOperator ImmNoSuOperator = immnosuoperator; /// Imm8Operand - This is the operand kind to use for an imm8 of this type. /// For example, i8 -> , i16 -> i16i8imm, i32 -> i32i8imm. This is /// only used for instructions that have a sign-extended imm8 field form. Operand Imm8Operand = imm8operand; /// Imm8Operator - This is the operator that should be used to match an 8-bit /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8). SDPatternOperator Imm8Operator = imm8operator; SDPatternOperator Imm8NoSuOperator = imm8nosuoperator; /// HasEvenOpcode - This bit is true if the instruction should have an even (as /// opposed to odd) opcode. Operations on i8 are even, operations on /// other datatypes are usually odd. bit HasEvenOpcode = hasEvenOpcode; /// HasREX_W - This bit is set to true if the instruction should have /// the 0x40 REX prefix. This is set for i64 types. bit HasREX_W = hasREX_W; } def invalid_node : SDNode<"<>", SDTIntLeaf,[],"<>">; def Xi8 : X86TypeInfo; def Xi16 : X86TypeInfo; def Xi32 : X86TypeInfo; def Xi64 : X86TypeInfo; // Group template arguments that can be derived from the vector type (EltNum x // EltVT). These are things like the register class for the writemask, etc. // The idea is to pass one of these as the template argument rather than the // individual arguments. // The template is also used for scalar types, in this case numelts is 1. class X86VectorVTInfo { RegisterClass RC = rc; ValueType EltVT = eltvt; int NumElts = numelts; // Corresponding mask register class. RegisterClass KRC = !cast("VK" # NumElts); // Corresponding mask register pair class. RegisterOperand KRPC = !if (!gt(NumElts, 16), ?, !cast("VK" # NumElts # "Pair")); // Corresponding write-mask register class. RegisterClass KRCWM = !cast("VK" # NumElts # "WM"); // The mask VT. ValueType KVT = !cast("v" # NumElts # "i1"); // Suffix used in the instruction mnemonic. string Suffix = suffix; // VTName is a string name for vector VT. For vector types it will be // v # NumElts # EltVT, so for vector of 8 elements of i32 it will be v8i32 // It is a little bit complex for scalar types, where NumElts = 1. // In this case we build v4f32 or v2f64 string VTName = "v" # !if (!eq (NumElts, 1), !if (!eq (EltVT.Size, 16), 8, !if (!eq (EltVT.Size, 32), 4, !if (!eq (EltVT.Size, 64), 2, NumElts))), NumElts) # EltVT; // The vector VT. ValueType VT = !cast(VTName); string EltTypeName = !cast(EltVT); // Size of the element type in bits, e.g. 32 for v16i32. string EltSizeName = !subst("i", "", !subst("f", "", !subst("b", "", EltTypeName))); int EltSize = EltVT.Size; // "i" for integer types and "f" for floating-point types string TypeVariantName = !subst("b", "", !subst(EltSizeName, "", EltTypeName)); // Size of RC in bits, e.g. 512 for VR512. int Size = VT.Size; // The corresponding memory operand, e.g. i512mem for VR512. X86MemOperand MemOp = !cast(TypeVariantName # Size # "mem"); X86MemOperand ScalarMemOp = !cast(!subst("b", "", EltTypeName) # "mem"); // FP scalar memory operand for intrinsics - ssmem/sdmem. Operand IntScalarMemOp = !if (!eq (EltTypeName, "f16"), !cast("shmem"), !if (!eq (EltTypeName, "bf16"), !cast("shmem"), !if (!eq (EltTypeName, "f32"), !cast("ssmem"), !if (!eq (EltTypeName, "f64"), !cast("sdmem"), ?)))); // Load patterns PatFrag LdFrag = !cast("load" # VTName); PatFrag AlignedLdFrag = !cast("alignedload" # VTName); PatFrag ScalarLdFrag = !cast("load" # !subst("b", "", EltTypeName)); PatFrag BroadcastLdFrag = !cast("X86VBroadcastld" # EltSizeName); PatFrags ScalarIntMemFrags = !if (!eq (EltTypeName, "f16"), !cast("sse_load_f16"), !if (!eq (EltTypeName, "bf16"), !cast("sse_load_f16"), !if (!eq (EltTypeName, "f32"), !cast("sse_load_f32"), !if (!eq (EltTypeName, "f64"), !cast("sse_load_f64"), ?)))); // The string to specify embedded broadcast in assembly. string BroadcastStr = "{1to" # NumElts # "}"; // 8-bit compressed displacement tuple/subvector format. This is only // defined for NumElts <= 8. CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0), !cast("CD8VT" # NumElts), ?); SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm, !if (!eq (Size, 256), sub_ymm, ?)); Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle, !if (!eq (EltTypeName, "f64"), SSEPackedDouble, !if (!eq (EltTypeName, "f16"), SSEPackedSingle, // FIXME? !if (!eq (EltTypeName, "bf16"), SSEPackedSingle, // FIXME? SSEPackedInt)))); RegisterClass FRC = !if (!eq (EltTypeName, "f32"), FR32X, !if (!eq (EltTypeName, "f16"), FR16X, !if (!eq (EltTypeName, "bf16"), FR16X, FR64X))); dag ImmAllZerosV = (VT immAllZerosV); string ZSuffix = !if (!eq (Size, 128), "Z128", !if (!eq (Size, 256), "Z256", "Z")); } def v64i8_info : X86VectorVTInfo<64, i8, VR512, "b">; def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">; def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">; def v8i64_info : X86VectorVTInfo<8, i64, VR512, "q">; def v32f16_info : X86VectorVTInfo<32, f16, VR512, "ph">; def v32bf16_info: X86VectorVTInfo<32, bf16, VR512, "pbf">; def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">; def v8f64_info : X86VectorVTInfo<8, f64, VR512, "pd">; // "x" in v32i8x_info means RC = VR256X def v32i8x_info : X86VectorVTInfo<32, i8, VR256X, "b">; def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">; def v8i32x_info : X86VectorVTInfo<8, i32, VR256X, "d">; def v4i64x_info : X86VectorVTInfo<4, i64, VR256X, "q">; def v16f16x_info : X86VectorVTInfo<16, f16, VR256X, "ph">; def v16bf16x_info: X86VectorVTInfo<16, bf16, VR256X, "pbf">; def v8f32x_info : X86VectorVTInfo<8, f32, VR256X, "ps">; def v4f64x_info : X86VectorVTInfo<4, f64, VR256X, "pd">; def v16i8x_info : X86VectorVTInfo<16, i8, VR128X, "b">; def v8i16x_info : X86VectorVTInfo<8, i16, VR128X, "w">; def v4i32x_info : X86VectorVTInfo<4, i32, VR128X, "d">; def v2i64x_info : X86VectorVTInfo<2, i64, VR128X, "q">; def v8f16x_info : X86VectorVTInfo<8, f16, VR128X, "ph">; def v8bf16x_info : X86VectorVTInfo<8, bf16, VR128X, "pbf">; def v4f32x_info : X86VectorVTInfo<4, f32, VR128X, "ps">; def v2f64x_info : X86VectorVTInfo<2, f64, VR128X, "pd">; // We map scalar types to the smallest (128-bit) vector type // with the appropriate element type. This allows to use the same masking logic. def i32x_info : X86VectorVTInfo<1, i32, GR32, "si">; def i64x_info : X86VectorVTInfo<1, i64, GR64, "sq">; def f16x_info : X86VectorVTInfo<1, f16, VR128X, "sh">; def bf16x_info : X86VectorVTInfo<1, bf16, VR128X, "sbf">; def f32x_info : X86VectorVTInfo<1, f32, VR128X, "ss">; def f64x_info : X86VectorVTInfo<1, f64, VR128X, "sd">; class AVX512VLVectorVTInfo { X86VectorVTInfo info512 = i512; X86VectorVTInfo info256 = i256; X86VectorVTInfo info128 = i128; } def avx512vl_i8_info : AVX512VLVectorVTInfo; def avx512vl_i16_info : AVX512VLVectorVTInfo; def avx512vl_i32_info : AVX512VLVectorVTInfo; def avx512vl_i64_info : AVX512VLVectorVTInfo; def avx512vl_f16_info : AVX512VLVectorVTInfo; def avx512vl_bf16_info : AVX512VLVectorVTInfo; def avx512vl_f32_info : AVX512VLVectorVTInfo; def avx512vl_f64_info : AVX512VLVectorVTInfo; class X86KVectorVTInfo { RegisterClass KRC = _krc; RegisterClass KRCWM = _krcwm; ValueType KVT = _vt; } def v1i1_info : X86KVectorVTInfo; def v2i1_info : X86KVectorVTInfo; def v4i1_info : X86KVectorVTInfo; def v8i1_info : X86KVectorVTInfo; def v16i1_info : X86KVectorVTInfo; def v32i1_info : X86KVectorVTInfo; def v64i1_info : X86KVectorVTInfo; // Subclasses of X86Inst class PseudoI pattern> : X86Inst<0, Pseudo, NoImm, oops, iops, ""> { let Pattern = pattern; } class I o, Format f, dag outs, dag ins, string asm, list pattern, Domain d = GenericDomain> : X86Inst { let Pattern = pattern; } class Ii8 o, Format f, dag outs, dag ins, string asm, list pattern, Domain d = GenericDomain> : X86Inst { let Pattern = pattern; } class Ii8Reg o, Format f, dag outs, dag ins, string asm, list pattern, Domain d = GenericDomain> : X86Inst { let Pattern = pattern; } class Ii8PCRel o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii16 o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii32 o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii32S o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii64 o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii16PCRel o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Ii32PCRel o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } // FPStack Instruction Templates: // FPI - Floating Point Instruction template. class FPI o, Format F, dag outs, dag ins, string asm> : I { let Defs = [FPSW]; let Predicates = [HasX87]; } // FpI_ - Floating Point Pseudo Instruction template. class FpI_ pattern> : PseudoI { let FPForm = fp; let Defs = [FPSW]; let Predicates = [HasX87]; } // Templates for instructions that use a 16- or 32-bit segmented address as // their only operand: lcall (FAR CALL) and ljmp (FAR JMP) // // Iseg16 - 16-bit segment selector, 16-bit offset // Iseg32 - 16-bit segment selector, 32-bit offset class Iseg16 o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } class Iseg32 o, Format f, dag outs, dag ins, string asm, list pattern> : X86Inst { let Pattern = pattern; } // SI - SSE 1 & 2 scalar instructions class SI o, Format F, dag outs, dag ins, string asm, list pattern, Domain d = GenericDomain> : I { let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512], !if(!eq(OpEnc.Value, EncVEX.Value), [UseAVX], !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1], !if(!eq(OpPrefix.Value, XD.Value), [UseSSE2], !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2], [UseSSE1]))))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm), !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm), asm)); } // SI - SSE 1 & 2 scalar intrinsics - vex form available on AVX512 class SI_Int o, Format F, dag outs, dag ins, string asm, list pattern, Domain d = GenericDomain> : I { let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512], !if(!eq(OpEnc.Value, EncVEX.Value), [UseAVX], !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1], !if(!eq(OpPrefix.Value, XD.Value), [UseSSE2], !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2], [UseSSE1]))))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm), !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm), asm)); } // SIi8 - SSE 1 & 2 scalar instructions - vex form available on AVX512 class SIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8 { let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512], !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX], !if(!eq(OpPrefix.Value, XS.Value), [UseSSE1], [UseSSE2]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm), !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm), asm)); } // PI - SSE 1 & 2 packed instructions class PI o, Format F, dag outs, dag ins, string asm, list pattern, Domain d> : I { let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512], !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX], !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2], [UseSSE1]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm), !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm), asm)); } // MMXPI - SSE 1 & 2 packed instructions with MMX operands class MMXPI o, Format F, dag outs, dag ins, string asm, list pattern, Domain d> : I { let Predicates = !if(!eq(OpPrefix.Value, PD.Value), [HasMMX, HasSSE2], [HasMMX, HasSSE1]); } // PIi8 - SSE 1 & 2 packed instructions with immediate class PIi8 o, Format F, dag outs, dag ins, string asm, list pattern, Domain d> : Ii8 { let Predicates = !if(!eq(OpEnc.Value, EncEVEX.Value), [HasAVX512], !if(!eq(OpEnc.Value, EncVEX.Value), [HasAVX], !if(!eq(OpPrefix.Value, PD.Value), [UseSSE2], [UseSSE1]))); // AVX instructions have a 'v' prefix in the mnemonic let AsmString = !if(!eq(OpEnc.Value, EncEVEX.Value), !strconcat("v", asm), !if(!eq(OpEnc.Value, EncVEX.Value), !strconcat("v", asm), asm)); } // SSE1 Instruction Templates: // // SSI - SSE1 instructions with XS prefix. // PSI - SSE1 instructions with PS prefix. // PSIi8 - SSE1 instructions with ImmT == Imm8 and PS prefix. // VSSI - SSE1 instructions with XS prefix in AVX form. // VPSI - SSE1 instructions with PS prefix in AVX form, packed single. class SSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[UseSSE1]>; class SSIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, XS, Requires<[UseSSE1]>; class PSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, Requires<[UseSSE1]>; class PSIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, Requires<[UseSSE1]>; class VSSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[HasAVX]>; class VPSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, Requires<[HasAVX]>; // SSE2 Instruction Templates: // // SDI - SSE2 instructions with XD prefix. // SDIi8 - SSE2 instructions with ImmT == Imm8 and XD prefix. // S2SI - SSE2 instructions with XS prefix. // SSDIi8 - SSE2 instructions with ImmT == Imm8 and XS prefix. // PDI - SSE2 instructions with PD prefix, packed double domain. // PDIi8 - SSE2 instructions with ImmT == Imm8 and PD prefix. // VSDI - SSE2 scalar instructions with XD prefix in AVX form. // VPDI - SSE2 vector instructions with PD prefix in AVX form, // packed double domain. // VS2I - SSE2 scalar instructions with PD prefix in AVX form. // S2I - SSE2 scalar instructions with PD prefix. // MMXSDIi8 - SSE2 instructions with ImmT == Imm8 and XD prefix as well as // MMX operands. // MMXSSDIi8 - SSE2 instructions with ImmT == Imm8 and XS prefix as well as // MMX operands. class SDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XD, Requires<[UseSSE2]>; class SDIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, XD, Requires<[UseSSE2]>; class S2SI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[UseSSE2]>; class S2SIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, XS, Requires<[UseSSE2]>; class PDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[UseSSE2]>; class PDIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, PD, Requires<[UseSSE2]>; class VSDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XD, Requires<[UseAVX]>; class VS2SI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[HasAVX]>; class VPDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[HasAVX]>; class VS2I o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[UseAVX]>; class S2I o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[UseSSE2]>; class MMXSDIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, XD, Requires<[HasMMX, HasSSE2]>; class MMXS2SIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, XS, Requires<[HasMMX, HasSSE2]>; // SSE3 Instruction Templates: // // S3I - SSE3 instructions with PD prefixes. // S3SI - SSE3 instructions with XS prefix. // S3DI - SSE3 instructions with XD prefix. class S3SI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[UseSSE3]>; class S3DI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XD, Requires<[UseSSE3]>; class S3I o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[UseSSE3]>; // SSSE3 Instruction Templates: // // SS38I - SSSE3 instructions with T8 prefix. // SS3AI - SSSE3 instructions with TA prefix. // MMXSS38I - SSSE3 instructions with T8 prefix and MMX operands. // MMXSS3AI - SSSE3 instructions with TA prefix and MMX operands. // // Note: SSSE3 instructions have 64-bit and 128-bit versions. The 64-bit version // uses the MMX registers. The 64-bit versions are grouped with the MMX // classes. They need to be enabled even if AVX is enabled. class SS38I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[UseSSSE3]>; class SS3AI o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[UseSSSE3]>; class MMXSS38I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, Requires<[HasMMX, HasSSSE3]>; class MMXSS3AI o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, Requires<[HasMMX, HasSSSE3]>; // SSE4.1 Instruction Templates: // // SS48I - SSE 4.1 instructions with T8 prefix. // SS41AIi8 - SSE 4.1 instructions with TA prefix and ImmT == Imm8. // class SS48I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[UseSSE41]>; class SS4AIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[UseSSE41]>; // SSE4.2 Instruction Templates: // // SS428I - SSE 4.2 instructions with T8 prefix. class SS428I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[UseSSE42]>; // SS42AI = SSE 4.2 instructions with TA prefix class SS42AI o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[UseSSE42]>; // AVX Instruction Templates: // Instructions introduced in AVX (no SSE equivalent forms) // // AVX8I - AVX instructions with T8, PD prefix. // AVXAIi8 - AVX instructions with TA, PD prefix and ImmT = Imm8. class AVX8I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[HasAVX]>; class AVXAIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[HasAVX]>; // AVX2 Instruction Templates: // Instructions introduced in AVX2 (no SSE equivalent forms) // // AVX28I - AVX2 instructions with T8, PD prefix. // AVX2AIi8 - AVX2 instructions with TA, PD prefix and ImmT = Imm8. class AVX28I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[HasAVX2]>; class AVX2AIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[HasAVX2]>; // AVX-512 Instruction Templates: // Instructions introduced in AVX-512 (no SSE equivalent forms) // // AVX5128I - AVX-512 instructions with T8, PD prefix. // AVX512AIi8 - AVX-512 instructions with TA, PD prefix and ImmT = Imm8. // AVX512PDI - AVX-512 instructions with PD, double packed. // AVX512PSI - AVX-512 instructions with PS, single packed. // AVX512XS8I - AVX-512 instructions with T8 and XS prefixes. // AVX512XSI - AVX-512 instructions with XS prefix, generic domain. // AVX512BI - AVX-512 instructions with PD, int packed domain. // AVX512SI - AVX-512 scalar instructions with PD prefix. class AVX5128I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, PD, Requires<[HasAVX512]>; class AVX5128IBase : T8, PD { Domain ExeDomain = SSEPackedInt; } class AVX512XS8I o, Format F, dag outs, dag ins, string asm, list pattern> : I, T8, XS, Requires<[HasAVX512]>; class AVX512XSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XS, Requires<[HasAVX512]>; class AVX512XDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, XD, Requires<[HasAVX512]>; class AVX512BI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[HasAVX512]>; class AVX512BIBase : TB, PD { Domain ExeDomain = SSEPackedInt; } class AVX512BIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, PD, Requires<[HasAVX512]>; class AVX512AIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[HasAVX512]>; class AVX512AIi8Base : TA, PD { ImmType ImmT = Imm8; } class AVX512Ii8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, Requires<[HasAVX512]>; class AVX512PDI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, PD, Requires<[HasAVX512]>; class AVX512PSI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, Requires<[HasAVX512]>; class AVX512PIi8 o, Format F, dag outs, dag ins, string asm, list pattern, Domain d> : Ii8, Requires<[HasAVX512]>; class AVX512PI o, Format F, dag outs, dag ins, string asm, list pattern, Domain d> : I, Requires<[HasAVX512]>; class AVX512FMA3S o, Format F, dag outs, dag ins, string asm, listpattern> : I, T8, PD, EVEX, VVVV, Requires<[HasAVX512]>; class AVX512 o, Format F, dag outs, dag ins, string asm, listpattern> : I, Requires<[HasAVX512]>; // AES Instruction Templates: // // AES8I // These use the same encoding as the SSE4.2 T8 and TA encodings. class AES8I o, Format F, dag outs, dag ins, string asm, listpattern> : I, T8, PD, Requires<[NoAVX, HasAES]>; class AESAI o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TA, PD, Requires<[NoAVX, HasAES]>; // PCLMUL Instruction Templates class PCLMULIi8 o, Format F, dag outs, dag ins, string asm, listpattern> : Ii8, TA, PD; // FMA3 Instruction Templates class FMA3 o, Format F, dag outs, dag ins, string asm, listpattern> : I, T8, PD, VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoVLX]>; class FMA3S o, Format F, dag outs, dag ins, string asm, listpattern> : I, T8, PD, VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoAVX512]>; class FMA3S_Int o, Format F, dag outs, dag ins, string asm, listpattern> : I, T8, PD, VEX, VVVV, FMASC, Requires<[HasFMA, NoAVX512]>; // FMA4 Instruction Templates class FMA4 o, Format F, dag outs, dag ins, string asm, listpattern> : Ii8Reg, TA, PD, VEX, VVVV, FMASC, Requires<[HasFMA4, NoVLX]>; class FMA4S o, Format F, dag outs, dag ins, string asm, listpattern> : Ii8Reg, TA, PD, VEX, VVVV, FMASC, Requires<[HasFMA4, NoAVX512]>; class FMA4S_Int o, Format F, dag outs, dag ins, string asm, listpattern> : Ii8Reg, TA, PD, VEX, VVVV, FMASC, Requires<[HasFMA4]>; // XOP 2, 3 and 4 Operand Instruction Template class IXOP o, Format F, dag outs, dag ins, string asm, list pattern> : I, XOP9, Requires<[HasXOP]>; // XOP 2 and 3 Operand Instruction Templates with imm byte class IXOPi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, XOP8, Requires<[HasXOP]>; // XOP 4 Operand Instruction Templates with imm byte class IXOPi8Reg o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8Reg, XOP8, Requires<[HasXOP]>; // XOP 5 operand instruction (VEX encoding!) class IXOP5 o, Format F, dag outs, dag ins, string asm, listpattern> : Ii8Reg, TA, PD, VEX, VVVV, Requires<[HasXOP]>; // X86-64 Instruction templates... // class RI o, Format F, dag outs, dag ins, string asm, list pattern> : I, REX_W; class RIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, REX_W; class RIi16 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii16, REX_W; class RIi32 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii32, REX_W; class RIi32S o, Format F, dag outs, dag ins, string asm, list pattern> : Ii32S, REX_W; class RIi64 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii64, REX_W; class RS2I o, Format F, dag outs, dag ins, string asm, list pattern> : S2I, REX_W; class VRS2I o, Format F, dag outs, dag ins, string asm, list pattern> : VS2I, REX_W; // MMX Instruction templates // // MMXI - MMX instructions with TB prefix. // MMXRI - MMX instructions with TB prefix and REX.W. // MMXIi8 - MMX instructions with ImmT == Imm8 and PS prefix. class MMXI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, Requires<[HasMMX]>; class MMXRI o, Format F, dag outs, dag ins, string asm, list pattern> : I, TB, REX_W, Requires<[HasMMX,In64BitMode]>; class MMXIi8 o, Format F, dag outs, dag ins, string asm, list pattern> : Ii8, TB, Requires<[HasMMX]>; /// ITy - This instruction base class takes the type info for the instruction. /// Using this, it: /// 1. Concatenates together the instruction mnemonic with the appropriate /// suffix letter, a tab, and the arguments. /// 2. Infers whether the instruction should have a 0x40 REX_W prefix. /// 3. Infers whether the low bit of the opcode should be 0 (for i8 operations) /// or 1 (for i16,i32,i64 operations). class ITy o, Format f, X86TypeInfo t, dag outs, dag ins, string m, string args, list p> : I<{o{7}, o{6}, o{5}, o{4}, o{3}, o{2}, o{1}, !if(!eq(t.HasEvenOpcode, 1), 0, o{0})}, f, outs, ins, !strconcat(m, "{", t.InstrSuffix, "}\t", args), p>, NoCD8 { let hasSideEffects = 0; let hasREX_W = t.HasREX_W; let IgnoresW = !if(!eq(t.VT, i8), 1, 0); } // BinOpRR - Instructions that read "reg, reg". class BinOpRR o, string m, string args, X86TypeInfo t, dag out, list p> : ITy, Sched<[WriteALU]>; // BinOpRR_F - Instructions that read "reg, reg" and write EFLAGS only. class BinOpRR_F o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpRR, DefEFLAGS; // BinOpRR_F_Rev - Reversed encoding of BinOpRR_F class BinOpRR_F_Rev o, string m, X86TypeInfo t> : BinOpRR_F, DisassembleOnly { let Form = MRMSrcReg; } // BinOpRR_R - Instructions that read "reg, reg" and write "reg". class BinOpRR_R o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRR, NDD; // BinOpRR_R_Rev - Reversed encoding of BinOpRR_R class BinOpRR_R_Rev o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRR_R, DisassembleOnly { let Form = MRMSrcReg; } // BinOpRR_RF - Instructions that read "reg, reg", and write "reg", EFLAGS. class BinOpRR_RF o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0> : BinOpRR, DefEFLAGS, NDD; // BinOpRR_RF_Rev - Reversed encoding of BinOpRR_RF. class BinOpRR_RF_Rev o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRR_RF, DisassembleOnly { let Form = MRMSrcReg; } // BinOpRRF_RF - Instructions that read "reg, reg", write "reg" and read/write // EFLAGS. class BinOpRRF_RF o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> : BinOpRR, DefEFLAGS, UseEFLAGS, NDD { let SchedRW = [WriteADC]; } // BinOpRRF_RF_Rev - Reversed encoding of BinOpRRF_RF class BinOpRRF_RF_Rev o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRRF_RF, DisassembleOnly { let Form = MRMSrcReg; } // BinOpRM - Instructions that read "reg, [mem]". class BinOpRM o, string m, string args, X86TypeInfo t, dag out, list p> : ITy, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]> { let mayLoad = 1; } // BinOpRM_F - Instructions that read "reg, [mem]" and write EFLAGS only. class BinOpRM_F o, string m, X86TypeInfo t, SDNode node> : BinOpRM, DefEFLAGS; // BinOpRM_R - Instructions that read "reg, [mem]", and write "reg". class BinOpRM_R o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRM, NDD; // BinOpRM_RF - Instructions that read "reg, [mem]", and write "reg", EFLAGS. class BinOpRM_RF o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0> : BinOpRM, DefEFLAGS, NDD; // BinOpRMF_RF - Instructions that read "reg, [mem]", write "reg" and read/write // EFLAGS. class BinOpRMF_RF o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> : BinOpRM, DefEFLAGS, UseEFLAGS, NDD { let SchedRW = [WriteADC.Folded, WriteADC.ReadAfterFold, // base, scale, index, offset, segment. ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, // implicit register read. WriteADC.ReadAfterFold]; } // BinOpRI - Instructions that read "reg, imm". class BinOpRI o, string m, string args, X86TypeInfo t, Format f, dag out, list p> : ITy, Sched<[WriteALU]> { let ImmT = t.ImmEncoding; } // BinOpRI_F - Instructions that read "reg, imm" and write EFLAGS only. class BinOpRI_F o, string m, X86TypeInfo t, SDPatternOperator node, Format f> : BinOpRI, DefEFLAGS; // BinOpRI_R - Instructions that read "reg, imm" and write "reg". class BinOpRI_R o, string m, X86TypeInfo t, Format f, bit ndd = 0> : BinOpRI, NDD; // BinOpRI8U_R - Instructions that read "reg, u8imm" and write "reg". class BinOpRI8U_R : ITy<0xC1, f, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, u8imm:$src2), m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), [(set t.RegClass:$dst, (node t.RegClass:$src1, (i8 imm:$src2)))]>, NDD { let ImmT = Imm8; } // BinOpRI_RF - Instructions that read "reg, imm" and write "reg", EFLAGS. class BinOpRI_RF o, string m, X86TypeInfo t, SDPatternOperator node, Format f, bit ndd = 0> : BinOpRI, DefEFLAGS, NDD; // BinOpRIF_RF - Instructions that read "reg, imm", write "reg" and read/write // EFLAGS. class BinOpRIF_RF o, string m, X86TypeInfo t, SDNode node, Format f, bit ndd = 0> : BinOpRI, DefEFLAGS, UseEFLAGS, NDD { let SchedRW = [WriteADC]; } // BinOpRI8 - Instructions that read "reg, imm8". class BinOpRI8 o, string m, string args, X86TypeInfo t, Format f, dag out> : ITy, Sched<[WriteALU]> { let ImmT = Imm8; } // BinOpRI8_F - Instructions that read "reg, imm8" and write EFLAGS only. class BinOpRI8_F o, string m, X86TypeInfo t, Format f> : BinOpRI8, DefEFLAGS; // BinOpRI8_R - Instructions that read "reg, imm8" and write "reg". class BinOpRI8_R o, string m, X86TypeInfo t, Format f, bit ndd = 0> : BinOpRI8, NDD; // BinOpRI8_RF - Instructions that read "reg, imm8" and write "reg", EFLAGS. class BinOpRI8_RF o, string m, X86TypeInfo t, Format f, bit ndd = 0> : BinOpRI8, DefEFLAGS, NDD; // BinOpRI8F_RF - Instructions that read "reg, imm", write "reg" and read/write // EFLAGS. class BinOpRI8F_RF o, string m, X86TypeInfo t, Format f, bit ndd = 0> : BinOpRI8, DefEFLAGS, UseEFLAGS, NDD { let SchedRW = [WriteADC]; } // BinOpMR - Instructions that read "[mem], reg". class BinOpMR o, string m, string args, X86TypeInfo t, dag out, list p> : ITy { let mayLoad = 1; let SchedRW = [WriteALU.Folded, WriteALU.ReadAfterFold]; } // BinOpMR_R - Instructions that read "[mem], reg", and write "reg". class BinOpMR_R o, string m, X86TypeInfo t> : BinOpMR, NDD<1>; // BinOpMR_RF - Instructions that read "[mem], reg", and write "reg", EFLAGS. class BinOpMR_RF o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpMR, DefEFLAGS, NDD<1>; // BinOpMR_F - Instructions that read "[mem], imm8" and write EFLAGS only. class BinOpMR_F o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpMR, Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>, DefEFLAGS; // BinOpMR_M - Instructions that read "[mem], reg" and write "[mem]". class BinOpMR_M o, string m, X86TypeInfo t> : BinOpMR, Sched<[WriteALURMW, // base, scale, index, offset, segment ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault]> { let mayStore = 1; } // BinOpMR_MF - Instructions that read "[mem], reg" and write "[mem]", EFLAGS. class BinOpMR_MF o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpMR, Sched<[WriteALURMW, // base, scale, index, offset, segment ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>, // reg DefEFLAGS { let mayStore = 1; } // BinOpMRF_RF - Instructions that read "[mem], reg", write "reg" and // read/write EFLAGS. class BinOpMRF_RF o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpMR, DefEFLAGS, UseEFLAGS, NDD<1>, Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>; // BinOpMRF_MF - Instructions that read "[mem], reg", write "[mem]" and // read/write EFLAGS. class BinOpMRF_MF o, string m, X86TypeInfo t, SDPatternOperator node> : BinOpMR, Sched<[WriteADCRMW, // base, scale, index, offset, segment ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, WriteALU.ReadAfterFold, // reg WriteALU.ReadAfterFold]>, // EFLAGS DefEFLAGS, UseEFLAGS { let mayStore = 1; } // BinOpMI - Instructions that read "[mem], imm". class BinOpMI o, string m, string args, X86TypeInfo t, Format f, dag out, list p> : ITy { let ImmT = t.ImmEncoding; let mayLoad = 1; } // BinOpMI_F - Instructions that read "[mem], imm" and write EFLAGS only. class BinOpMI_F o, string m, X86TypeInfo t, SDPatternOperator node, Format f> : BinOpMI, Sched<[WriteALU.Folded]>, DefEFLAGS; // BinOpMI_R - Instructions that read "[mem], imm" and write "reg". class BinOpMI_R o, string m, X86TypeInfo t, Format f> : BinOpMI, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>; // BinOpMI_R - Instructions that read "[mem], imm" and write "reg", EFLAGS. class BinOpMI_RF o, string m, X86TypeInfo t, SDPatternOperator node, Format f> : BinOpMI, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>; // BinOpMI_M - Instructions that read "[mem], imm" and write "[mem]". class BinOpMI_M o, string m, X86TypeInfo t, Format f> : BinOpMI, Sched<[WriteALURMW]> { let mayStore = 1; } // BinOpMI_MF - Instructions that read "[mem], imm" and write "[mem]", EFLAGS. class BinOpMI_MF o, string m, X86TypeInfo t, SDPatternOperator node, Format f> : BinOpMI, Sched<[WriteALURMW]>, DefEFLAGS { let mayStore = 1; } // BinOpMIF_RF - Instructions that read "[mem], imm", write "reg" and // read/write EFLAGS. class BinOpMIF_RF o, string m, X86TypeInfo t, SDNode node, Format f> : BinOpMI, Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>, DefEFLAGS, UseEFLAGS, NDD<1>; // BinOpMIF_MF - Instructions that read "[mem], imm", write "[mem]" and // read/write EFLAGS. class BinOpMIF_MF o, string m, X86TypeInfo t, SDNode node, Format f> : BinOpMI, Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS { let mayStore = 1; } // BinOpMI8 - Instructions that read "[mem], imm8". class BinOpMI8 : ITy<0x83, f, t, out, (ins t.MemOperand:$src1, t.Imm8Operand:$src2), m, args, []> { let ImmT = Imm8; let mayLoad = 1; } // BinOpMI8U - Instructions that read "[mem], u8imm". class BinOpMI8U p> : ITy<0xC1, f, t, out, (ins t.MemOperand:$src1, u8imm:$src2), m, args, p> { let ImmT = Imm8; let mayLoad = 1; } // BinOpMI8_F - Instructions that read "[mem], imm8" and write EFLAGS only. class BinOpMI8_F : BinOpMI8, Sched<[WriteALU.Folded]>, DefEFLAGS; // BinOpMI8_R - Instructions that read "[mem], imm8" and write "reg". class BinOpMI8_R : BinOpMI8, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>; // BinOpMI8U_R - Instructions that read "[mem], u8imm" and write "reg". class BinOpMI8U_R : BinOpMI8U, NDD<1>; // BinOpMI8_RF - Instructions that read "[mem], imm8" and write "reg"/EFLAGS. class BinOpMI8_RF : BinOpMI8, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>; // BinOpMI8_M - Instructions that read "[mem], imm8" and write "[mem]". class BinOpMI8_M : BinOpMI8, Sched<[WriteALURMW]> { let mayStore = 1; } // BinOpMI8U_M - Instructions that read "[mem], u8imm" and write "[mem]". class BinOpMI8U_M : BinOpMI8U { let mayStore = 1; } // BinOpMI8_MF - Instructions that read "[mem], imm8" and write "[mem]", EFLAGS. class BinOpMI8_MF : BinOpMI8, Sched<[WriteALURMW]>, DefEFLAGS { let mayStore = 1; } // BinOpMI8F_RF - Instructions that read "[mem], imm8", write "reg" and // read/write EFLAGS. class BinOpMI8F_RF : BinOpMI8, Sched<[WriteADC.Folded, WriteADC.ReadAfterFold]>, DefEFLAGS, UseEFLAGS, NDD<1>; // BinOpMI8F_MF - Instructions that read "[mem], imm8", write "[mem]" and // read/write EFLAGS. class BinOpMI8F_MF : BinOpMI8, Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS { let mayStore = 1; } // BinOpAI - Instructions that read "a-reg imm" (Accumulator register). class BinOpAI o, string m, X86TypeInfo t, Register areg, string args> : ITy, Sched<[WriteALU]> { let ImmT = t.ImmEncoding; let Uses = [areg]; } // BinOpAI_F - Instructions that read "a-reg imm" and write EFLAGS only. class BinOpAI_F o, string m, X86TypeInfo t, Register areg, string args> : BinOpAI, DefEFLAGS; // BinOpAI_AF - Instructions that read "a-reg imm" and write a-reg/EFLAGS. class BinOpAI_AF o, string m, X86TypeInfo t, Register areg, string args> : BinOpAI { let Defs = [areg, EFLAGS]; } // BinOpAIF_AF - Instructions that read "a-reg imm", write a-reg and read/write // EFLAGS. class BinOpAIF_AF o, string m, X86TypeInfo t, Register areg, string args> : BinOpAI { let Uses = [areg, EFLAGS]; let Defs = [areg, EFLAGS]; let SchedRW = [WriteADC]; } // BinOpRC_R - Instructions that read "reg, cl" and write reg. class BinOpRC_R : ITy<0xD3, f, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1), m, !if(!eq(ndd, 0), binop_cl_args, binop_cl_ndd_args), [(set t.RegClass:$dst, (node t.RegClass:$src1, CL))]>, NDD { let Uses = [CL]; } // BinOpMC_M - Instructions that read "[mem], cl" and write [mem]. class BinOpMC_M : ITy<0xD3, f, t, (outs), (ins t.MemOperand:$src1), m, binop_cl_args, [(store (node (t.LoadNode addr:$src1), CL), addr:$src1)]> { let Uses = [CL]; let mayLoad = 1; let mayStore = 1; } // BinOpMC_R - Instructions that read "[mem], cl" and write reg. class BinOpMC_R : ITy<0xD3, f, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1), m, binop_cl_ndd_args, [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), CL))]>, NDD<1> { let Uses = [CL]; let mayLoad = 1; } // UnaryOpR - Instructions that read "reg". class UnaryOpR o, Format f, string m, string args, X86TypeInfo t, dag out, list p> : ITy, Sched<[WriteALU]>; // UnaryOpR_R - Instructions that read "reg" and write "reg". class UnaryOpR_R o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> : UnaryOpR, NDD; // UnaryOpR_RF - Instructions that read "reg" and write "reg"/EFLAGS. class UnaryOpR_RF o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0> : UnaryOpR, DefEFLAGS, NDD; // UnaryOpM - Instructions that read "[mem]". class UnaryOpM o, Format f, string m, string args, X86TypeInfo t, dag out, list p> : ITy { let mayLoad = 1; } // UnaryOpM_R - Instructions that read "[mem]" and writes "reg". class UnaryOpM_R o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag> : UnaryOpM, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>; // UnaryOpM_RF - Instructions that read "[mem]" and writes "reg"/EFLAGS. class UnaryOpM_RF o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag> : UnaryOpM, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>; // UnaryOpM_M - Instructions that read "[mem]" and writes "[mem]". class UnaryOpM_M o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag> : UnaryOpM, Sched<[WriteALURMW]>{ let mayStore = 1; } // UnaryOpM_MF - Instructions that read "[mem]" and writes "[mem]"/EFLAGS. class UnaryOpM_MF o, Format f, string m, X86TypeInfo t, SDPatternOperator node = null_frag> : UnaryOpM, Sched<[WriteALURMW]>, DefEFLAGS { let mayStore = 1; }