//===-- 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<Register> 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 esize, CD8VForm form> {
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<Register> Defs = [EFLAGS]; }
class UseEFLAGS { list<Register> 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<bit 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<ValueType vt, string instrsuffix, RegisterClass regclass,
PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
Operand immoperand, SDPatternOperator immoperator,
SDPatternOperator immnosuoperator, Operand imm8operand,
SDPatternOperator imm8operator, SDPatternOperator imm8nosuoperator,
bit hasEvenOpcode, bit hasREX_W> {
/// 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 -> <invalid>, 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<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
def Xi8 : X86TypeInfo<i8, "b", GR8, loadi8, i8mem, Imm8, i8imm,
imm_su, imm, i8imm, invalid_node, invalid_node,
1, 0>;
def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem, Imm16, i16imm,
imm_su, imm, i16i8imm, i16immSExt8_su, i16immSExt8,
0, 0>;
def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem, Imm32, i32imm,
imm_su, imm, i32i8imm, i32immSExt8_su, i32immSExt8,
0, 0>;
def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem, Imm32S, i64i32imm,
i64immSExt32_su, i64immSExt32, i64i8imm, i64immSExt8_su,
i64immSExt8, 0, 1>;
// 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<int numelts, ValueType eltvt, RegisterClass rc,
string suffix = ""> {
RegisterClass RC = rc;
ValueType EltVT = eltvt;
int NumElts = numelts;
// Corresponding mask register class.
RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
// Corresponding mask register pair class.
RegisterOperand KRPC = !if (!gt(NumElts, 16), ?,
!cast<RegisterOperand>("VK" # NumElts # "Pair"));
// Corresponding write-mask register class.
RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
// The mask VT.
ValueType KVT = !cast<ValueType>("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<ValueType>(VTName);
string EltTypeName = !cast<string>(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<X86MemOperand>(TypeVariantName # Size # "mem");
X86MemOperand ScalarMemOp = !cast<X86MemOperand>(!subst("b", "", EltTypeName) # "mem");
// FP scalar memory operand for intrinsics - ssmem/sdmem.
Operand IntScalarMemOp = !if (!eq (EltTypeName, "f16"), !cast<Operand>("shmem"),
!if (!eq (EltTypeName, "bf16"), !cast<Operand>("shmem"),
!if (!eq (EltTypeName, "f32"), !cast<Operand>("ssmem"),
!if (!eq (EltTypeName, "f64"), !cast<Operand>("sdmem"), ?))));
// Load patterns
PatFrag LdFrag = !cast<PatFrag>("load" # VTName);
PatFrag AlignedLdFrag = !cast<PatFrag>("alignedload" # VTName);
PatFrag ScalarLdFrag = !cast<PatFrag>("load" # !subst("b", "", EltTypeName));
PatFrag BroadcastLdFrag = !cast<PatFrag>("X86VBroadcastld" # EltSizeName);
PatFrags ScalarIntMemFrags = !if (!eq (EltTypeName, "f16"), !cast<PatFrags>("sse_load_f16"),
!if (!eq (EltTypeName, "bf16"), !cast<PatFrags>("sse_load_f16"),
!if (!eq (EltTypeName, "f32"), !cast<PatFrags>("sse_load_f32"),
!if (!eq (EltTypeName, "f64"), !cast<PatFrags>("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<CD8VForm>("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, "pbf16">;
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, "pbf16">;
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, "pbf16">;
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 i512, X86VectorVTInfo i256,
X86VectorVTInfo i128> {
X86VectorVTInfo info512 = i512;
X86VectorVTInfo info256 = i256;
X86VectorVTInfo info128 = i128;
}
def avx512vl_i8_info : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
v16i8x_info>;
def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
v8i16x_info>;
def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
v4i32x_info>;
def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
v2i64x_info>;
def avx512vl_f16_info : AVX512VLVectorVTInfo<v32f16_info, v16f16x_info,
v8f16x_info>;
def avx512vl_bf16_info : AVX512VLVectorVTInfo<v32bf16_info, v16bf16x_info,
v8bf16x_info>;
def avx512vl_f32_info : AVX512VLVectorVTInfo<v16f32_info, v8f32x_info,
v4f32x_info>;
def avx512vl_f64_info : AVX512VLVectorVTInfo<v8f64_info, v4f64x_info,
v2f64x_info>;
class X86KVectorVTInfo<RegisterClass _krc, RegisterClass _krcwm,
ValueType _vt> {
RegisterClass KRC = _krc;
RegisterClass KRCWM = _krcwm;
ValueType KVT = _vt;
}
def v1i1_info : X86KVectorVTInfo<VK1, VK1WM, v1i1>;
def v2i1_info : X86KVectorVTInfo<VK2, VK2WM, v2i1>;
def v4i1_info : X86KVectorVTInfo<VK4, VK4WM, v4i1>;
def v8i1_info : X86KVectorVTInfo<VK8, VK8WM, v8i1>;
def v16i1_info : X86KVectorVTInfo<VK16, VK16WM, v16i1>;
def v32i1_info : X86KVectorVTInfo<VK32, VK32WM, v32i1>;
def v64i1_info : X86KVectorVTInfo<VK64, VK64WM, v64i1>;
// Subclasses of X86Inst
class PseudoI<dag oops, dag iops, list<dag> pattern>
: X86Inst<0, Pseudo, NoImm, oops, iops, ""> {
let Pattern = pattern;
}
class I<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern, Domain d = GenericDomain>
: X86Inst<o, f, NoImm, outs, ins, asm, d> {
let Pattern = pattern;
}
class Ii8<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern, Domain d = GenericDomain>
: X86Inst<o, f, Imm8, outs, ins, asm, d> {
let Pattern = pattern;
}
class Ii8Reg<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern, Domain d = GenericDomain>
: X86Inst<o, f, Imm8Reg, outs, ins, asm, d> {
let Pattern = pattern;
}
class Ii8PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm8PCRel, outs, ins, asm> {
let Pattern = pattern;
}
class Ii16<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm16, outs, ins, asm> {
let Pattern = pattern;
}
class Ii32<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm32, outs, ins, asm> {
let Pattern = pattern;
}
class Ii32S<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm32S, outs, ins, asm> {
let Pattern = pattern;
}
class Ii64<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm64, outs, ins, asm> {
let Pattern = pattern;
}
class Ii16PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm16PCRel, outs, ins, asm> {
let Pattern = pattern;
}
class Ii32PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm32PCRel, outs, ins, asm> {
let Pattern = pattern;
}
// FPStack Instruction Templates:
// FPI - Floating Point Instruction template.
class FPI<bits<8> o, Format F, dag outs, dag ins, string asm>
: I<o, F, outs, ins, asm, []> {
let Defs = [FPSW];
let Predicates = [HasX87];
}
// FpI_ - Floating Point Pseudo Instruction template.
class FpI_<dag outs, dag ins, FPFormat fp, list<dag> pattern>
: PseudoI<outs, ins, pattern> {
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 <bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm16, outs, ins, asm> {
let Pattern = pattern;
}
class Iseg32 <bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm32, outs, ins, asm> {
let Pattern = pattern;
}
// SI - SSE 1 & 2 scalar instructions
class SI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern, Domain d = GenericDomain>
: I<o, F, outs, ins, asm, pattern, d> {
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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern, Domain d = GenericDomain>
: I<o, F, outs, ins, asm, pattern, d> {
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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern> {
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<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern,
Domain d>
: I<o, F, outs, ins, asm, pattern, d> {
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<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern,
Domain d>
: I<o, F, outs, ins, asm, pattern, d> {
let Predicates = !if(!eq(OpPrefix.Value, PD.Value), [HasMMX, HasSSE2],
[HasMMX, HasSSE1]);
}
// PIi8 - SSE 1 & 2 packed instructions with immediate
class PIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern, Domain d>
: Ii8<o, F, outs, ins, asm, pattern, d> {
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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE1]>;
class SSIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE1]>;
class PSI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
Requires<[UseSSE1]>;
class PSIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
Requires<[UseSSE1]>;
class VSSI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XS,
Requires<[HasAVX]>;
class VPSI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern, SSEPackedSingle>,
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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[UseSSE2]>;
class SDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[UseSSE2]>;
class S2SI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE2]>;
class S2SIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, TB, XS, Requires<[UseSSE2]>;
class PDI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
Requires<[UseSSE2]>;
class PDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
Requires<[UseSSE2]>;
class VSDI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XD,
Requires<[UseAVX]>;
class VS2SI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, XS,
Requires<[HasAVX]>;
class VPDI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern, SSEPackedDouble>,
TB, PD, Requires<[HasAVX]>;
class VS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, !strconcat("v", asm), pattern>, TB, PD,
Requires<[UseAVX]>;
class S2I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, PD, Requires<[UseSSE2]>;
class MMXSDIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, TB, XD, Requires<[HasMMX, HasSSE2]>;
class MMXS2SIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB, XS,
Requires<[UseSSE3]>;
class S3DI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, XD,
Requires<[UseSSE3]>;
class S3I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[UseSSSE3]>;
class SS3AI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
Requires<[UseSSSE3]>;
class MMXSS38I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8,
Requires<[HasMMX, HasSSSE3]>;
class MMXSS3AI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[UseSSE41]>;
class SS4AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
Requires<[UseSSE41]>;
// SSE4.2 Instruction Templates:
//
// SS428I - SSE 4.2 instructions with T8 prefix.
class SS428I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[UseSSE42]>;
// SS42AI = SSE 4.2 instructions with TA prefix
class SS42AI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[HasAVX]>;
class AVXAIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[HasAVX2]>;
class AVX2AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[HasAVX512]>;
class AVX5128IBase : T8, PD {
Domain ExeDomain = SSEPackedInt;
}
class AVX512XS8I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, XS,
Requires<[HasAVX512]>;
class AVX512XSI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, XS,
Requires<[HasAVX512]>;
class AVX512XDI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, XD,
Requires<[HasAVX512]>;
class AVX512BI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, PD,
Requires<[HasAVX512]>;
class AVX512BIBase : TB, PD {
Domain ExeDomain = SSEPackedInt;
}
class AVX512BIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TB, PD,
Requires<[HasAVX512]>;
class AVX512AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
Requires<[HasAVX512]>;
class AVX512AIi8Base : TA, PD {
ImmType ImmT = Imm8;
}
class AVX512Ii8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>,
Requires<[HasAVX512]>;
class AVX512PDI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedDouble>, TB, PD,
Requires<[HasAVX512]>;
class AVX512PSI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedSingle>, TB,
Requires<[HasAVX512]>;
class AVX512PIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern, Domain d>
: Ii8<o, F, outs, ins, asm, pattern, d>, Requires<[HasAVX512]>;
class AVX512PI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern, Domain d>
: I<o, F, outs, ins, asm, pattern, d>, Requires<[HasAVX512]>;
class AVX512FMA3S<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern>, T8, PD,
EVEX, VVVV, Requires<[HasAVX512]>;
class AVX512<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern>, Requires<[HasAVX512]>;
// AES Instruction Templates:
//
// AES8I
// These use the same encoding as the SSE4.2 T8 and TA encodings.
class AES8I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8, PD,
Requires<[NoAVX, HasAES]>;
class AESAI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
Requires<[NoAVX, HasAES]>;
// PCLMUL Instruction Templates
class PCLMULIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD;
// FMA3 Instruction Templates
class FMA3<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern>, T8, PD,
VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoVLX]>;
class FMA3S<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern>, T8, PD,
VEX, VVVV, FMASC, Requires<[HasFMA, NoFMA4, NoAVX512]>;
class FMA3S_Int<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern>, T8, PD,
VEX, VVVV, FMASC, Requires<[HasFMA, NoAVX512]>;
// FMA4 Instruction Templates
class FMA4<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
VEX, VVVV, FMASC, Requires<[HasFMA4, NoVLX]>;
class FMA4S<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
VEX, VVVV, FMASC, Requires<[HasFMA4, NoAVX512]>;
class FMA4S_Int<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: Ii8Reg<o, F, outs, ins, asm, pattern>, TA, PD,
VEX, VVVV, FMASC, Requires<[HasFMA4]>;
// XOP 2, 3 and 4 Operand Instruction Template
class IXOP<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
XOP9, Requires<[HasXOP]>;
// XOP 2 and 3 Operand Instruction Templates with imm byte
class IXOPi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
XOP8, Requires<[HasXOP]>;
// XOP 4 Operand Instruction Templates with imm byte
class IXOPi8Reg<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8Reg<o, F, outs, ins, asm, pattern, SSEPackedDouble>,
XOP8, Requires<[HasXOP]>;
// XOP 5 operand instruction (VEX encoding!)
class IXOP5<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: Ii8Reg<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA, PD,
VEX, VVVV, Requires<[HasXOP]>;
// X86-64 Instruction templates...
//
class RI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, REX_W;
class RIi8 <bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, REX_W;
class RIi16 <bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii16<o, F, outs, ins, asm, pattern>, REX_W;
class RIi32 <bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii32<o, F, outs, ins, asm, pattern>, REX_W;
class RIi32S <bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii32S<o, F, outs, ins, asm, pattern>, REX_W;
class RIi64<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii64<o, F, outs, ins, asm, pattern>, REX_W;
class RS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: S2I<o, F, outs, ins, asm, pattern>, REX_W;
class VRS2I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: VS2I<o, F, outs, ins, asm, pattern>, 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<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, Requires<[HasMMX]>;
class MMXRI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, TB, REX_W,
Requires<[HasMMX,In64BitMode]>;
class MMXIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern>, 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<bits<8> o, Format f, X86TypeInfo t, dag outs, dag ins, string m,
string args, list<dag> 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<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
: ITy<o, MRMDestReg, t, out, (ins t.RegClass:$src1, t.RegClass:$src2), m,
args, p>, Sched<[WriteALU]>;
// BinOpRR_F - Instructions that read "reg, reg" and write EFLAGS only.
class BinOpRR_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpRR<o, m, binop_args, t, (outs),
[(set EFLAGS, (node t.RegClass:$src1, t.RegClass:$src2))]>,
DefEFLAGS;
// BinOpRR_F_Rev - Reversed encoding of BinOpRR_F
class BinOpRR_F_Rev<bits<8> o, string m, X86TypeInfo t>
: BinOpRR_F<o, m, t, null_frag>, DisassembleOnly {
let Form = MRMSrcReg;
}
// BinOpRR_R - Instructions that read "reg, reg" and write "reg".
class BinOpRR_R<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
: BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t,
(outs t.RegClass:$dst), []>, NDD<ndd>;
// BinOpRR_R_Rev - Reversed encoding of BinOpRR_R
class BinOpRR_R_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
: BinOpRR_R<o, m, t, ndd>, DisassembleOnly {
let Form = MRMSrcReg;
}
// BinOpRR_RF - Instructions that read "reg, reg", and write "reg", EFLAGS.
class BinOpRR_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0>
: BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t,
(outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS,
(node t.RegClass:$src1, t.RegClass:$src2))]>, DefEFLAGS, NDD<ndd>;
// BinOpRR_RF_Rev - Reversed encoding of BinOpRR_RF.
class BinOpRR_RF_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
: BinOpRR_RF<o, m, t, null_frag, ndd>, DisassembleOnly {
let Form = MRMSrcReg;
}
// BinOpRRF_RF - Instructions that read "reg, reg", write "reg" and read/write
// EFLAGS.
class BinOpRRF_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
: BinOpRR<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS,
(node t.RegClass:$src1, t.RegClass:$src2,
EFLAGS))]>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
let SchedRW = [WriteADC];
}
// BinOpRRF_RF_Rev - Reversed encoding of BinOpRRF_RF
class BinOpRRF_RF_Rev<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
: BinOpRRF_RF<o, m, t, null_frag, ndd>, DisassembleOnly {
let Form = MRMSrcReg;
}
// BinOpRM - Instructions that read "reg, [mem]".
class BinOpRM<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
: ITy<o, MRMSrcMem, t, out, (ins t.RegClass:$src1, t.MemOperand:$src2), m,
args, p>,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]> {
let mayLoad = 1;
}
// BinOpRM_F - Instructions that read "reg, [mem]" and write EFLAGS only.
class BinOpRM_F<bits<8> o, string m, X86TypeInfo t, SDNode node>
: BinOpRM<o, m, binop_args, t, (outs),
[(set EFLAGS, (node t.RegClass:$src1,
(t.LoadNode addr:$src2)))]>, DefEFLAGS;
// BinOpRM_R - Instructions that read "reg, [mem]", and write "reg".
class BinOpRM_R<bits<8> o, string m, X86TypeInfo t, bit ndd = 0>
: BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
[]>, NDD<ndd>;
// BinOpRM_RF - Instructions that read "reg, [mem]", and write "reg", EFLAGS.
class BinOpRM_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0>
: BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node t.RegClass:$src1,
(t.LoadNode addr:$src2)))]>, DefEFLAGS, NDD<ndd>;
// BinOpRMF_RF - Instructions that read "reg, [mem]", write "reg" and read/write
// EFLAGS.
class BinOpRMF_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
: BinOpRM<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS,
(node t.RegClass:$src1, (t.LoadNode addr:$src2), EFLAGS))]>,
DefEFLAGS, UseEFLAGS, NDD<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<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out, list<dag> p>
: ITy<o, f, t, out, (ins t.RegClass:$src1, t.ImmOperand:$src2), m,
args, p>, Sched<[WriteALU]> {
let ImmT = t.ImmEncoding;
}
// BinOpRI_F - Instructions that read "reg, imm" and write EFLAGS only.
class BinOpRI_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
Format f>
: BinOpRI<o, m, binop_args, t, f, (outs),
[(set EFLAGS, (node t.RegClass:$src1,
t.ImmOperator:$src2))]>, DefEFLAGS;
// BinOpRI_R - Instructions that read "reg, imm" and write "reg".
class BinOpRI_R<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
: BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
[]>, NDD<ndd>;
// BinOpRI8U_R - Instructions that read "reg, u8imm" and write "reg".
class BinOpRI8U_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
: 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<ndd> {
let ImmT = Imm8;
}
// BinOpRI_RF - Instructions that read "reg, imm" and write "reg", EFLAGS.
class BinOpRI_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, Format f, bit ndd = 0>
: BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS,
(node t.RegClass:$src1, t.ImmOperator:$src2))]>, DefEFLAGS, NDD<ndd>;
// BinOpRIF_RF - Instructions that read "reg, imm", write "reg" and read/write
// EFLAGS.
class BinOpRIF_RF<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f, bit ndd = 0>
: BinOpRI<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS,
(node t.RegClass:$src1, t.ImmOperator:$src2,
EFLAGS))]>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
let SchedRW = [WriteADC];
}
// BinOpRI8 - Instructions that read "reg, imm8".
class BinOpRI8<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out>
: ITy<o, f, t, out, (ins t.RegClass:$src1, t.Imm8Operand:$src2), m,
args, []>, Sched<[WriteALU]> {
let ImmT = Imm8;
}
// BinOpRI8_F - Instructions that read "reg, imm8" and write EFLAGS only.
class BinOpRI8_F<bits<8> o, string m, X86TypeInfo t, Format f>
: BinOpRI8<o, m, binop_args, t, f, (outs)>, DefEFLAGS;
// BinOpRI8_R - Instructions that read "reg, imm8" and write "reg".
class BinOpRI8_R<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
: BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, NDD<ndd>;
// BinOpRI8_RF - Instructions that read "reg, imm8" and write "reg", EFLAGS.
class BinOpRI8_RF<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
: BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, DefEFLAGS, NDD<ndd>;
// BinOpRI8F_RF - Instructions that read "reg, imm", write "reg" and read/write
// EFLAGS.
class BinOpRI8F_RF<bits<8> o, string m, X86TypeInfo t, Format f, bit ndd = 0>
: BinOpRI8<o, m, !if(!eq(ndd, 0), binop_args, binop_ndd_args), t, f, (outs t.RegClass:$dst)>, DefEFLAGS, UseEFLAGS, NDD<ndd> {
let SchedRW = [WriteADC];
}
// BinOpMR - Instructions that read "[mem], reg".
class BinOpMR<bits<8> o, string m, string args, X86TypeInfo t, dag out, list<dag> p>
: ITy<o, MRMDestMem, t, out, (ins t.MemOperand:$src1, t.RegClass:$src2), m,
args, p> {
let mayLoad = 1;
let SchedRW = [WriteALU.Folded, WriteALU.ReadAfterFold];
}
// BinOpMR_R - Instructions that read "[mem], reg", and write "reg".
class BinOpMR_R<bits<8> o, string m, X86TypeInfo t>
: BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst), []>, NDD<1>;
// BinOpMR_RF - Instructions that read "[mem], reg", and write "reg", EFLAGS.
class BinOpMR_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1),
t.RegClass:$src2))]>, DefEFLAGS, NDD<1>;
// BinOpMR_F - Instructions that read "[mem], imm8" and write EFLAGS only.
class BinOpMR_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpMR<o, m, binop_args, t, (outs),
[(set EFLAGS, (node (t.LoadNode addr:$src1), t.RegClass:$src2))]>,
Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault,
ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>, DefEFLAGS;
// BinOpMR_M - Instructions that read "[mem], reg" and write "[mem]".
class BinOpMR_M<bits<8> o, string m, X86TypeInfo t>
: BinOpMR<o, m, binop_args, t, (outs), []>,
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<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpMR<o, m, binop_args, t, (outs),
[(store (node (load addr:$src1), t.RegClass:$src2), addr:$src1),
(implicit EFLAGS)]>,
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<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node (load addr:$src1),
t.RegClass:$src2, EFLAGS))]>, 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<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node>
: BinOpMR<o, m, binop_args, t, (outs),
[(store (node (load addr:$src1), t.RegClass:$src2, EFLAGS),
addr:$src1), (implicit EFLAGS)]>,
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<bits<8> o, string m, string args, X86TypeInfo t, Format f, dag out, list<dag> p>
: ITy<o, f, t, out, (ins t.MemOperand:$src1, t.ImmOperand:$src2), m,
args, p> {
let ImmT = t.ImmEncoding;
let mayLoad = 1;
}
// BinOpMI_F - Instructions that read "[mem], imm" and write EFLAGS only.
class BinOpMI_F<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
Format f>
: BinOpMI<o, m, binop_args, t, f, (outs),
[(set EFLAGS, (node (t.LoadNode addr:$src1), t.ImmOperator:$src2))]>,
Sched<[WriteALU.Folded]>, DefEFLAGS;
// BinOpMI_R - Instructions that read "[mem], imm" and write "reg".
class BinOpMI_R<bits<8> o, string m, X86TypeInfo t, Format f>
: BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst), []>,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
// BinOpMI_R - Instructions that read "[mem], imm" and write "reg", EFLAGS.
class BinOpMI_RF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
Format f>
: BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1), t.ImmOperator:$src2))]>,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
// BinOpMI_M - Instructions that read "[mem], imm" and write "[mem]".
class BinOpMI_M<bits<8> o, string m, X86TypeInfo t, Format f>
: BinOpMI<o, m, binop_args, t, f, (outs), []>, Sched<[WriteALURMW]> {
let mayStore = 1;
}
// BinOpMI_MF - Instructions that read "[mem], imm" and write "[mem]", EFLAGS.
class BinOpMI_MF<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, Format f>
: BinOpMI<o, m, binop_args, t, f, (outs),
[(store (node (t.VT (load addr:$src1)),
t.ImmOperator:$src2), addr:$src1), (implicit EFLAGS)]>,
Sched<[WriteALURMW]>, DefEFLAGS {
let mayStore = 1;
}
// BinOpMIF_RF - Instructions that read "[mem], imm", write "reg" and
// read/write EFLAGS.
class BinOpMIF_RF<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f>
: BinOpMI<o, m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node (t.VT (load addr:$src1)),
t.ImmOperator:$src2, EFLAGS))]>,
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<bits<8> o, string m, X86TypeInfo t, SDNode node, Format f>
: BinOpMI<o, m, binop_args, t, f, (outs),
[(store (node (t.VT (load addr:$src1)),
t.ImmOperator:$src2, EFLAGS), addr:$src1), (implicit EFLAGS)]>,
Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS {
let mayStore = 1;
}
// BinOpMI8 - Instructions that read "[mem], imm8".
class BinOpMI8<string m, string args, X86TypeInfo t, Format f, dag out>
: 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<string m, string args, X86TypeInfo t, Format f, dag out, list<dag> 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<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALU.Folded]>, DefEFLAGS;
// BinOpMI8_R - Instructions that read "[mem], imm8" and write "reg".
class BinOpMI8_R<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
// BinOpMI8U_R - Instructions that read "[mem], u8imm" and write "reg".
class BinOpMI8U_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
: BinOpMI8U<m, binop_ndd_args, t, f, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, (node (t.LoadNode addr:$src1), (i8 imm:$src2)))]>, NDD<1>;
// BinOpMI8_RF - Instructions that read "[mem], imm8" and write "reg"/EFLAGS.
class BinOpMI8_RF<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
// BinOpMI8_M - Instructions that read "[mem], imm8" and write "[mem]".
class BinOpMI8_M<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALURMW]> {
let mayStore = 1;
}
// BinOpMI8U_M - Instructions that read "[mem], u8imm" and write "[mem]".
class BinOpMI8U_M<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
: BinOpMI8U<m, binop_args, t, f, (outs),
[(store (node (t.LoadNode addr:$src1), (i8 imm:$src2)), addr:$src1)]> {
let mayStore = 1;
}
// BinOpMI8_MF - Instructions that read "[mem], imm8" and write "[mem]", EFLAGS.
class BinOpMI8_MF<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteALURMW]>, DefEFLAGS {
let mayStore = 1;
}
// BinOpMI8F_RF - Instructions that read "[mem], imm8", write "reg" and
// read/write EFLAGS.
class BinOpMI8F_RF<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_ndd_args, t, f, (outs t.RegClass:$dst)>,
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<string m, X86TypeInfo t, Format f>
: BinOpMI8<m, binop_args, t, f, (outs)>, Sched<[WriteADCRMW]>, DefEFLAGS, UseEFLAGS {
let mayStore = 1;
}
// BinOpAI - Instructions that read "a-reg imm" (Accumulator register).
class BinOpAI<bits<8> o, string m, X86TypeInfo t, Register areg, string args>
: ITy<o, RawFrm, t, (outs), (ins t.ImmOperand:$src), m, args, []>,
Sched<[WriteALU]> {
let ImmT = t.ImmEncoding;
let Uses = [areg];
}
// BinOpAI_F - Instructions that read "a-reg imm" and write EFLAGS only.
class BinOpAI_F<bits<8> o, string m, X86TypeInfo t, Register areg, string args>
: BinOpAI<o, m, t, areg, args>, DefEFLAGS;
// BinOpAI_AF - Instructions that read "a-reg imm" and write a-reg/EFLAGS.
class BinOpAI_AF<bits<8> o, string m, X86TypeInfo t, Register areg,
string args> : BinOpAI<o, m, t, areg, args> {
let Defs = [areg, EFLAGS];
}
// BinOpAIF_AF - Instructions that read "a-reg imm", write a-reg and read/write
// EFLAGS.
class BinOpAIF_AF<bits<8> o, string m, X86TypeInfo t, Register areg,
string args> : BinOpAI<o, m, t, areg, args> {
let Uses = [areg, EFLAGS];
let Defs = [areg, EFLAGS];
let SchedRW = [WriteADC];
}
// BinOpRC_R - Instructions that read "reg, cl" and write reg.
class BinOpRC_R<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>
: 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<ndd> {
let Uses = [CL];
}
// BinOpMC_M - Instructions that read "[mem], cl" and write [mem].
class BinOpMC_M<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
: 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<string m, Format f, X86TypeInfo t, SDPatternOperator node = null_frag>
: 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<bits<8> o, Format f, string m, string args, X86TypeInfo t,
dag out, list<dag> p>
: ITy<o, f, t, out, (ins t.RegClass:$src1), m, args, p>, Sched<[WriteALU]>;
// UnaryOpR_R - Instructions that read "reg" and write "reg".
class UnaryOpR_R<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag, bit ndd = 0>
: UnaryOpR<o, f, m, !if(!eq(ndd, 0), unaryop_args, unaryop_ndd_args), t,
(outs t.RegClass:$dst),
[(set t.RegClass:$dst, (node t.RegClass:$src1))]>, NDD<ndd>;
// UnaryOpR_RF - Instructions that read "reg" and write "reg"/EFLAGS.
class UnaryOpR_RF<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag, bit ndd = 0>
: UnaryOpR<o, f, m, !if(!eq(ndd, 0), unaryop_args, unaryop_ndd_args), t,
(outs t.RegClass:$dst),
[(set t.RegClass:$dst, (node t.RegClass:$src1)),
(implicit EFLAGS)]>, DefEFLAGS, NDD<ndd>;
// UnaryOpM - Instructions that read "[mem]".
class UnaryOpM<bits<8> o, Format f, string m, string args, X86TypeInfo t,
dag out, list<dag> p>
: ITy<o, f, t, out, (ins t.MemOperand:$src1), m, args, p> {
let mayLoad = 1;
}
// UnaryOpM_R - Instructions that read "[mem]" and writes "reg".
class UnaryOpM_R<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag>
: UnaryOpM<o, f, m, unaryop_ndd_args, t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, (node (t.LoadNode addr:$src1)))]>,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, NDD<1>;
// UnaryOpM_RF - Instructions that read "[mem]" and writes "reg"/EFLAGS.
class UnaryOpM_RF<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag>
: UnaryOpM<o, f, m, unaryop_ndd_args, t, (outs t.RegClass:$dst),
[(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1)))]>,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, DefEFLAGS, NDD<1>;
// UnaryOpM_M - Instructions that read "[mem]" and writes "[mem]".
class UnaryOpM_M<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag>
: UnaryOpM<o, f, m, unaryop_args, t, (outs),
[(store (node (t.LoadNode addr:$src1)), addr:$src1)]>,
Sched<[WriteALURMW]>{
let mayStore = 1;
}
// UnaryOpM_MF - Instructions that read "[mem]" and writes "[mem]"/EFLAGS.
class UnaryOpM_MF<bits<8> o, Format f, string m, X86TypeInfo t,
SDPatternOperator node = null_frag>
: UnaryOpM<o, f, m, unaryop_args, t, (outs),
[(store (node (t.LoadNode addr:$src1)), addr:$src1),
(implicit EFLAGS)]>, Sched<[WriteALURMW]>, DefEFLAGS {
let mayStore = 1;
}