• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===-- X86InstrXOP.td - XOP Instruction Set ---------------*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes XOP (eXtended OPerations)
11//
12//===----------------------------------------------------------------------===//
13
14multiclass xop2op<bits<8> opc, string OpcodeStr, Intrinsic Int, PatFrag memop> {
15  def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
16           !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
17           [(set VR128:$dst, (Int VR128:$src))]>, VEX;
18  def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
19           !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
20           [(set VR128:$dst, (Int (bitconvert (memop addr:$src))))]>, VEX;
21}
22
23let isAsmParserOnly = 1 in {
24  defm VPHSUBWD  : xop2op<0xE2, "vphsubwd", int_x86_xop_vphsubwd, memopv2i64>;
25  defm VPHSUBDQ  : xop2op<0xE3, "vphsubdq", int_x86_xop_vphsubdq, memopv2i64>;
26  defm VPHSUBBW  : xop2op<0xE1, "vphsubbw", int_x86_xop_vphsubbw, memopv2i64>;
27  defm VPHADDWQ  : xop2op<0xC7, "vphaddwq", int_x86_xop_vphaddwq, memopv2i64>;
28  defm VPHADDWD  : xop2op<0xC6, "vphaddwd", int_x86_xop_vphaddwd, memopv2i64>;
29  defm VPHADDUWQ : xop2op<0xD7, "vphadduwq", int_x86_xop_vphadduwq, memopv2i64>;
30  defm VPHADDUWD : xop2op<0xD6, "vphadduwd", int_x86_xop_vphadduwd, memopv2i64>;
31  defm VPHADDUDQ : xop2op<0xDB, "vphaddudq", int_x86_xop_vphaddudq, memopv2i64>;
32  defm VPHADDUBW : xop2op<0xD1, "vphaddubw", int_x86_xop_vphaddubw, memopv2i64>;
33  defm VPHADDUBQ : xop2op<0xD3, "vphaddubq", int_x86_xop_vphaddubq, memopv2i64>;
34  defm VPHADDUBD : xop2op<0xD2, "vphaddubd", int_x86_xop_vphaddubd, memopv2i64>;
35  defm VPHADDDQ  : xop2op<0xCB, "vphadddq", int_x86_xop_vphadddq, memopv2i64>;
36  defm VPHADDBW  : xop2op<0xC1, "vphaddbw", int_x86_xop_vphaddbw, memopv2i64>;
37  defm VPHADDBQ  : xop2op<0xC3, "vphaddbq", int_x86_xop_vphaddbq, memopv2i64>;
38  defm VPHADDBD  : xop2op<0xC2, "vphaddbd", int_x86_xop_vphaddbd, memopv2i64>;
39  defm VFRCZPS   : xop2op<0x80, "vfrczps", int_x86_xop_vfrcz_ps, memopv4f32>;
40  defm VFRCZPD   : xop2op<0x81, "vfrczpd", int_x86_xop_vfrcz_pd, memopv2f64>;
41}
42
43// Scalar load 2 addr operand instructions
44let Constraints = "$src1 = $dst" in {
45multiclass xop2opsld<bits<8> opc, string OpcodeStr, Intrinsic Int,
46                     Operand memop, ComplexPattern mem_cpat> {
47  def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1,
48                                                        VR128:$src2),
49           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
50           [(set VR128:$dst, (Int VR128:$src1, VR128:$src2))]>, VEX;
51  def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1,
52                                                        memop:$src2),
53           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
54           [(set VR128:$dst, (Int VR128:$src1,
55                                  (bitconvert mem_cpat:$src2)))]>, VEX;
56}
57
58} // Constraints = "$src1 = $dst"
59
60let isAsmParserOnly = 1 in {
61  defm VFRCZSS   : xop2opsld<0x82, "vfrczss", int_x86_xop_vfrcz_ss,
62                   ssmem, sse_load_f32>;
63  defm VFRCZSD   : xop2opsld<0x83, "vfrczsd", int_x86_xop_vfrcz_sd,
64                   sdmem, sse_load_f64>;
65}
66
67
68multiclass xop2op256<bits<8> opc, string OpcodeStr, Intrinsic Int,
69                     PatFrag memop> {
70  def rrY : IXOP<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
71           !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
72           [(set VR256:$dst, (Int VR256:$src))]>, VEX, VEX_L;
73  def rmY : IXOP<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
74           !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
75           [(set VR256:$dst, (Int (bitconvert (memop addr:$src))))]>, VEX;
76}
77
78let isAsmParserOnly = 1 in {
79  defm VFRCZPS : xop2op256<0x80, "vfrczps", int_x86_xop_vfrcz_ps_256,
80                           memopv8f32>;
81  defm VFRCZPD : xop2op256<0x81, "vfrczpd", int_x86_xop_vfrcz_pd_256,
82                           memopv4f64>;
83}
84
85multiclass xop3op<bits<8> opc, string OpcodeStr, Intrinsic Int> {
86  def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst),
87           (ins VR128:$src1, VR128:$src2),
88           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
89           [(set VR128:$dst, (Int VR128:$src1, VR128:$src2))]>, VEX_4VOp3;
90  def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst),
91           (ins VR128:$src1, f128mem:$src2),
92           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
93           [(set VR128:$dst,
94              (Int VR128:$src1, (bitconvert (memopv2i64 addr:$src2))))]>,
95           VEX_4V, VEX_W;
96  def mr : IXOP<opc, MRMSrcMem, (outs VR128:$dst),
97           (ins f128mem:$src1, VR128:$src2),
98           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
99           [(set VR128:$dst,
100              (Int (bitconvert (memopv2i64 addr:$src1)), VR128:$src2))]>,
101             VEX_4VOp3;
102}
103
104let isAsmParserOnly = 1 in {
105  defm VPSHLW : xop3op<0x95, "vpshlw", int_x86_xop_vpshlw>;
106  defm VPSHLQ : xop3op<0x97, "vpshlq", int_x86_xop_vpshlq>;
107  defm VPSHLD : xop3op<0x96, "vpshld", int_x86_xop_vpshld>;
108  defm VPSHLB : xop3op<0x94, "vpshlb", int_x86_xop_vpshlb>;
109  defm VPSHAW : xop3op<0x99, "vpshaw", int_x86_xop_vpshaw>;
110  defm VPSHAQ : xop3op<0x9B, "vpshaq", int_x86_xop_vpshaq>;
111  defm VPSHAD : xop3op<0x9A, "vpshad", int_x86_xop_vpshad>;
112  defm VPSHAB : xop3op<0x98, "vpshab", int_x86_xop_vpshab>;
113  defm VPROTW : xop3op<0x91, "vprotw", int_x86_xop_vprotw>;
114  defm VPROTQ : xop3op<0x93, "vprotq", int_x86_xop_vprotq>;
115  defm VPROTD : xop3op<0x92, "vprotd", int_x86_xop_vprotd>;
116  defm VPROTB : xop3op<0x90, "vprotb", int_x86_xop_vprotb>;
117}
118
119multiclass xop3opimm<bits<8> opc, string OpcodeStr> {
120  let neverHasSideEffects = 1 in {
121    def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst),
122             (ins VR128:$src1, i8imm:$src2),
123             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
124             []>, VEX;
125    let mayLoad = 1 in
126    def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst),
127             (ins f128mem:$src1, i8imm:$src2),
128             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
129             []>, VEX;
130  }
131}
132
133let isAsmParserOnly = 1 in {
134  defm VPROTW : xop3opimm<0xC1, "vprotw">;
135  defm VPROTQ : xop3opimm<0xC3, "vprotq">;
136  defm VPROTD : xop3opimm<0xC2, "vprotd">;
137  defm VPROTB : xop3opimm<0xC0, "vprotb">;
138}
139
140// Instruction where second source can be memory, but third must be register
141multiclass xop4opm2<bits<8> opc, string OpcodeStr, Intrinsic Int> {
142  def rr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst),
143           (ins VR128:$src1, VR128:$src2, VR128:$src3),
144           !strconcat(OpcodeStr,
145           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
146           [(set VR128:$dst,
147              (Int VR128:$src1, VR128:$src2, VR128:$src3))]>, VEX_4V, VEX_I8IMM;
148  def rm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst),
149           (ins VR128:$src1, f128mem:$src2, VR128:$src3),
150           !strconcat(OpcodeStr,
151           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
152           [(set VR128:$dst,
153              (Int VR128:$src1, (bitconvert (memopv2i64 addr:$src2)),
154              VR128:$src3))]>, VEX_4V, VEX_I8IMM;
155}
156
157let isAsmParserOnly = 1 in {
158  defm VPMADCSWD  : xop4opm2<0xB6, "vpmadcswd", int_x86_xop_vpmadcswd>;
159  defm VPMADCSSWD : xop4opm2<0xA6, "vpmadcsswd", int_x86_xop_vpmadcsswd>;
160  defm VPMACSWW   : xop4opm2<0x95, "vpmacsww", int_x86_xop_vpmacsww>;
161  defm VPMACSWD   : xop4opm2<0x96, "vpmacswd", int_x86_xop_vpmacswd>;
162  defm VPMACSSWW  : xop4opm2<0x85, "vpmacssww", int_x86_xop_vpmacssww>;
163  defm VPMACSSWD  : xop4opm2<0x86, "vpmacsswd", int_x86_xop_vpmacsswd>;
164  defm VPMACSSDQL : xop4opm2<0x87, "vpmacssdql", int_x86_xop_vpmacssdql>;
165  defm VPMACSSDQH : xop4opm2<0x8F, "vpmacssdqh", int_x86_xop_vpmacssdqh>;
166  defm VPMACSSDD  : xop4opm2<0x8E, "vpmacssdd", int_x86_xop_vpmacssdd>;
167  defm VPMACSDQL  : xop4opm2<0x97, "vpmacsdql", int_x86_xop_vpmacsdql>;
168  defm VPMACSDQH  : xop4opm2<0x9F, "vpmacsdqh", int_x86_xop_vpmacsdqh>;
169  defm VPMACSDD   : xop4opm2<0x9E, "vpmacsdd", int_x86_xop_vpmacsdd>;
170}
171
172// Instruction where second source can be memory, third must be imm8
173multiclass xop4opimm<bits<8> opc, string OpcodeStr, SDNode OpNode,
174                     ValueType VT> {
175  def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst),
176           (ins VR128:$src1, VR128:$src2, i8imm:$src3),
177           !strconcat(OpcodeStr,
178           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
179           [(set VR128:$dst,
180             (VT (OpNode VR128:$src1, VR128:$src2, imm:$src3)))]>, VEX_4V;
181  def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst),
182           (ins VR128:$src1, f128mem:$src2, i8imm:$src3),
183           !strconcat(OpcodeStr,
184           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
185           [(set VR128:$dst,
186             (VT (OpNode VR128:$src1, (bitconvert (memopv2i64 addr:$src2)),
187                  imm:$src3)))]>, VEX_4V;
188}
189
190let isAsmParserOnly = 1 in {
191  defm VPCOMB  : xop4opimm<0xCC, "vpcomb", X86vpcom, v16i8>;
192  defm VPCOMW  : xop4opimm<0xCD, "vpcomw", X86vpcom, v8i16>;
193  defm VPCOMD  : xop4opimm<0xCE, "vpcomd", X86vpcom, v4i32>;
194  defm VPCOMQ  : xop4opimm<0xCF, "vpcomq", X86vpcom, v2i64>;
195  defm VPCOMUB : xop4opimm<0xEC, "vpcomub", X86vpcomu, v16i8>;
196  defm VPCOMUW : xop4opimm<0xED, "vpcomuw", X86vpcomu, v8i16>;
197  defm VPCOMUD : xop4opimm<0xEE, "vpcomud", X86vpcomu, v4i32>;
198  defm VPCOMUQ : xop4opimm<0xEF, "vpcomuq", X86vpcomu, v2i64>;
199}
200
201// Instruction where either second or third source can be memory
202multiclass xop4op<bits<8> opc, string OpcodeStr, Intrinsic Int> {
203  def rr : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst),
204           (ins VR128:$src1, VR128:$src2, VR128:$src3),
205           !strconcat(OpcodeStr,
206           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
207           [(set VR128:$dst, (Int VR128:$src1, VR128:$src2, VR128:$src3))]>,
208           VEX_4V, VEX_I8IMM;
209  def rm : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst),
210           (ins VR128:$src1, VR128:$src2, f128mem:$src3),
211           !strconcat(OpcodeStr,
212           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
213           [(set VR128:$dst,
214             (Int VR128:$src1, VR128:$src2,
215              (bitconvert (memopv2i64 addr:$src3))))]>,
216           VEX_4V, VEX_I8IMM, VEX_W, MemOp4;
217  def mr : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst),
218           (ins VR128:$src1, f128mem:$src2, VR128:$src3),
219           !strconcat(OpcodeStr,
220           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
221           [(set VR128:$dst,
222             (Int VR128:$src1, (bitconvert (memopv2i64 addr:$src2)),
223              VR128:$src3))]>,
224           VEX_4V, VEX_I8IMM;
225}
226
227let isAsmParserOnly = 1 in {
228  defm VPPERM : xop4op<0xA3, "vpperm", int_x86_xop_vpperm>;
229  defm VPCMOV : xop4op<0xA2, "vpcmov", int_x86_xop_vpcmov>;
230}
231
232multiclass xop4op256<bits<8> opc, string OpcodeStr, Intrinsic Int> {
233  def rrY : IXOPi8<opc, MRMSrcReg, (outs VR256:$dst),
234           (ins VR256:$src1, VR256:$src2, VR256:$src3),
235           !strconcat(OpcodeStr,
236           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
237           [(set VR256:$dst, (Int VR256:$src1, VR256:$src2, VR256:$src3))]>,
238           VEX_4V, VEX_I8IMM;
239  def rmY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst),
240           (ins VR256:$src1, VR256:$src2, f256mem:$src3),
241           !strconcat(OpcodeStr,
242           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
243           [(set VR256:$dst,
244             (Int VR256:$src1, VR256:$src2,
245              (bitconvert (memopv4i64 addr:$src3))))]>,
246           VEX_4V, VEX_I8IMM, VEX_W, MemOp4;
247  def mrY : IXOPi8<opc, MRMSrcMem, (outs VR256:$dst),
248           (ins VR256:$src1, f256mem:$src2, VR256:$src3),
249           !strconcat(OpcodeStr,
250           "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
251           [(set VR256:$dst,
252             (Int VR256:$src1, (bitconvert (memopv4i64 addr:$src2)),
253              VR256:$src3))]>,
254           VEX_4V, VEX_I8IMM;
255}
256
257let isAsmParserOnly = 1 in {
258  defm VPCMOV : xop4op256<0xA2, "vpcmov", int_x86_xop_vpcmov_256>;
259}
260
261multiclass xop5op<bits<8> opc, string OpcodeStr, Intrinsic Int128,
262                  Intrinsic Int256, PatFrag ld_128, PatFrag ld_256> {
263  def rr : IXOP5<opc, MRMSrcReg, (outs VR128:$dst),
264        (ins VR128:$src1, VR128:$src2, VR128:$src3, i8imm:$src4),
265        !strconcat(OpcodeStr,
266        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
267        [(set VR128:$dst,
268           (Int128 VR128:$src1, VR128:$src2, VR128:$src3, imm:$src4))]>;
269  def rm : IXOP5<opc, MRMSrcMem, (outs VR128:$dst),
270        (ins VR128:$src1, VR128:$src2, f128mem:$src3, i8imm:$src4),
271        !strconcat(OpcodeStr,
272        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
273        [(set VR128:$dst,
274           (Int128 VR128:$src1, VR128:$src2, (ld_128 addr:$src3), imm:$src4))]>,
275        VEX_W, MemOp4;
276  def mr : IXOP5<opc, MRMSrcMem, (outs VR128:$dst),
277        (ins VR128:$src1, f128mem:$src2, VR128:$src3, i8imm:$src4),
278        !strconcat(OpcodeStr,
279        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
280        [(set VR128:$dst,
281           (Int128 VR128:$src1, (ld_128 addr:$src2), VR128:$src3, imm:$src4))]>;
282  def rrY : IXOP5<opc, MRMSrcReg, (outs VR256:$dst),
283        (ins VR256:$src1, VR256:$src2, VR256:$src3, i8imm:$src4),
284        !strconcat(OpcodeStr,
285        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
286        [(set VR256:$dst,
287          (Int256 VR256:$src1, VR256:$src2, VR256:$src3, imm:$src4))]>;
288  def rmY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst),
289        (ins VR256:$src1, VR256:$src2, f256mem:$src3, i8imm:$src4),
290        !strconcat(OpcodeStr,
291        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
292        [(set VR256:$dst,
293          (Int256 VR256:$src1, VR256:$src2, (ld_256 addr:$src3), imm:$src4))]>,
294        VEX_W, MemOp4;
295  def mrY : IXOP5<opc, MRMSrcMem, (outs VR256:$dst),
296        (ins VR256:$src1, f256mem:$src2, VR256:$src3, i8imm:$src4),
297        !strconcat(OpcodeStr,
298        "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"),
299        [(set VR256:$dst,
300           (Int256 VR256:$src1, (ld_256 addr:$src2), VR256:$src3, imm:$src4))]>;
301}
302
303defm VPERMIL2PD : xop5op<0x49, "vpermil2pd", int_x86_xop_vpermil2pd,
304                         int_x86_xop_vpermil2pd_256, memopv2f64, memopv4f64>;
305defm VPERMIL2PS : xop5op<0x48, "vpermil2ps", int_x86_xop_vpermil2ps,
306                         int_x86_xop_vpermil2ps_256, memopv4f32, memopv8f32>;
307
308