~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Target/ARM/ARMInstrNEON.td

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- ARMInstrNEON.td - NEON support for ARM -----------------------------===//
 
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 the ARM NEON instruction set.
 
11
//
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
//===----------------------------------------------------------------------===//
 
15
// NEON-specific DAG Nodes.
 
16
//===----------------------------------------------------------------------===//
 
17
 
 
18
def SDTARMVCMP    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>;
 
19
 
 
20
def NEONvceq      : SDNode<"ARMISD::VCEQ", SDTARMVCMP>;
 
21
def NEONvcge      : SDNode<"ARMISD::VCGE", SDTARMVCMP>;
 
22
def NEONvcgeu     : SDNode<"ARMISD::VCGEU", SDTARMVCMP>;
 
23
def NEONvcgt      : SDNode<"ARMISD::VCGT", SDTARMVCMP>;
 
24
def NEONvcgtu     : SDNode<"ARMISD::VCGTU", SDTARMVCMP>;
 
25
def NEONvtst      : SDNode<"ARMISD::VTST", SDTARMVCMP>;
 
26
 
 
27
// Types for vector shift by immediates.  The "SHX" version is for long and
 
28
// narrow operations where the source and destination vectors have different
 
29
// types.  The "SHINS" version is for shift and insert operations.
 
30
def SDTARMVSH     : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
 
31
                                         SDTCisVT<2, i32>]>;
 
32
def SDTARMVSHX    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
 
33
                                         SDTCisVT<2, i32>]>;
 
34
def SDTARMVSHINS  : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
 
35
                                         SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
 
36
 
 
37
def NEONvshl      : SDNode<"ARMISD::VSHL", SDTARMVSH>;
 
38
def NEONvshrs     : SDNode<"ARMISD::VSHRs", SDTARMVSH>;
 
39
def NEONvshru     : SDNode<"ARMISD::VSHRu", SDTARMVSH>;
 
40
def NEONvshlls    : SDNode<"ARMISD::VSHLLs", SDTARMVSHX>;
 
41
def NEONvshllu    : SDNode<"ARMISD::VSHLLu", SDTARMVSHX>;
 
42
def NEONvshlli    : SDNode<"ARMISD::VSHLLi", SDTARMVSHX>;
 
43
def NEONvshrn     : SDNode<"ARMISD::VSHRN", SDTARMVSHX>;
 
44
 
 
45
def NEONvrshrs    : SDNode<"ARMISD::VRSHRs", SDTARMVSH>;
 
46
def NEONvrshru    : SDNode<"ARMISD::VRSHRu", SDTARMVSH>;
 
47
def NEONvrshrn    : SDNode<"ARMISD::VRSHRN", SDTARMVSHX>;
 
48
 
 
49
def NEONvqshls    : SDNode<"ARMISD::VQSHLs", SDTARMVSH>;
 
50
def NEONvqshlu    : SDNode<"ARMISD::VQSHLu", SDTARMVSH>;
 
51
def NEONvqshlsu   : SDNode<"ARMISD::VQSHLsu", SDTARMVSH>;
 
52
def NEONvqshrns   : SDNode<"ARMISD::VQSHRNs", SDTARMVSHX>;
 
53
def NEONvqshrnu   : SDNode<"ARMISD::VQSHRNu", SDTARMVSHX>;
 
54
def NEONvqshrnsu  : SDNode<"ARMISD::VQSHRNsu", SDTARMVSHX>;
 
55
 
 
56
def NEONvqrshrns  : SDNode<"ARMISD::VQRSHRNs", SDTARMVSHX>;
 
57
def NEONvqrshrnu  : SDNode<"ARMISD::VQRSHRNu", SDTARMVSHX>;
 
58
def NEONvqrshrnsu : SDNode<"ARMISD::VQRSHRNsu", SDTARMVSHX>;
 
59
 
 
60
def NEONvsli      : SDNode<"ARMISD::VSLI", SDTARMVSHINS>;
 
61
def NEONvsri      : SDNode<"ARMISD::VSRI", SDTARMVSHINS>;
 
62
 
 
63
def SDTARMVGETLN  : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>,
 
64
                                         SDTCisVT<2, i32>]>;
 
65
def NEONvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>;
 
66
def NEONvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>;
 
67
 
 
68
def NEONvdup      : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
 
69
 
 
70
// VDUPLANE can produce a quad-register result from a double-register source,
 
71
// so the result is not constrained to match the source.
 
72
def NEONvduplane  : SDNode<"ARMISD::VDUPLANE",
 
73
                           SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
 
74
                                                SDTCisVT<2, i32>]>>;
 
75
 
 
76
def SDTARMVEXT    : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
 
77
                                         SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>;
 
78
def NEONvext      : SDNode<"ARMISD::VEXT", SDTARMVEXT>;
 
79
 
 
80
def SDTARMVSHUF   : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
 
81
def NEONvrev64    : SDNode<"ARMISD::VREV64", SDTARMVSHUF>;
 
82
def NEONvrev32    : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
 
83
def NEONvrev16    : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
 
84
 
 
85
def SDTARMVSHUF2  : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>,
 
86
                                         SDTCisSameAs<0, 2>,
 
87
                                         SDTCisSameAs<0, 3>]>;
 
88
def NEONzip       : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>;
 
89
def NEONuzp       : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>;
 
90
def NEONtrn       : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>;
 
91
 
 
92
def SDTARMFMAX    : SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisSameAs<0, 1>,
 
93
                                         SDTCisSameAs<0, 2>]>;
 
94
def NEONfmax      : SDNode<"ARMISD::FMAX", SDTARMFMAX>;
 
95
def NEONfmin      : SDNode<"ARMISD::FMIN", SDTARMFMAX>;
 
96
 
 
97
//===----------------------------------------------------------------------===//
 
98
// NEON operand definitions
 
99
//===----------------------------------------------------------------------===//
 
100
 
 
101
// addrmode_neonldstm := reg
 
102
//
 
103
/* TODO: Take advantage of vldm.
 
104
def addrmode_neonldstm : Operand<i32>,
 
105
                ComplexPattern<i32, 2, "SelectAddrModeNeonLdStM", []> {
 
106
  let PrintMethod = "printAddrNeonLdStMOperand";
 
107
  let MIOperandInfo = (ops GPR, i32imm);
 
108
}
 
109
*/
 
110
 
 
111
def h8imm  : Operand<i8> {
 
112
  let PrintMethod = "printHex8ImmOperand";
 
113
}
 
114
def h16imm : Operand<i16> {
 
115
  let PrintMethod = "printHex16ImmOperand";
 
116
}
 
117
def h32imm : Operand<i32> {
 
118
  let PrintMethod = "printHex32ImmOperand";
 
119
}
 
120
def h64imm : Operand<i64> {
 
121
  let PrintMethod = "printHex64ImmOperand";
 
122
}
 
123
 
 
124
//===----------------------------------------------------------------------===//
 
125
// NEON load / store instructions
 
126
//===----------------------------------------------------------------------===//
 
127
 
 
128
/* TODO: Take advantage of vldm.
 
129
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
 
130
def VLDMD : NI<(outs),
 
131
               (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
 
132
               IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
 
133
  let Inst{27-25} = 0b110;
 
134
  let Inst{20}    = 1;
 
135
  let Inst{11-9}  = 0b101;
 
136
}
 
137
 
 
138
def VLDMS : NI<(outs),
 
139
               (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
 
140
               IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
 
141
  let Inst{27-25} = 0b110;
 
142
  let Inst{20}    = 1;
 
143
  let Inst{11-9}  = 0b101;
 
144
}
 
145
}
 
146
*/
 
147
 
 
148
// Use vldmia to load a Q register as a D register pair.
 
149
def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
 
150
                "vldmia", "$addr, ${dst:dregpair}",
 
151
                [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
 
152
  let Inst{27-25} = 0b110;
 
153
  let Inst{24}    = 0; // P bit
 
154
  let Inst{23}    = 1; // U bit
 
155
  let Inst{20}    = 1;
 
156
  let Inst{11-8}  = 0b1011;
 
157
}
 
158
 
 
159
// Use vstmia to store a Q register as a D register pair.
 
160
def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem,
 
161
                "vstmia", "$addr, ${src:dregpair}",
 
162
                [(store (v2f64 QPR:$src), addrmode4:$addr)]> {
 
163
  let Inst{27-25} = 0b110;
 
164
  let Inst{24}    = 0; // P bit
 
165
  let Inst{23}    = 1; // U bit
 
166
  let Inst{20}    = 0;
 
167
  let Inst{11-8}  = 0b1011;
 
168
}
 
169
 
 
170
//   VLD1     : Vector Load (multiple single elements)
 
171
class VLD1D<bits<4> op7_4, string OpcodeStr, string Dt,
 
172
            ValueType Ty, Intrinsic IntOp>
 
173
  : NLdSt<0,0b10,0b0111,op7_4, (outs DPR:$dst), (ins addrmode6:$addr), IIC_VLD1,
 
174
          OpcodeStr, Dt, "\\{$dst\\}, $addr", "",
 
175
          [(set DPR:$dst, (Ty (IntOp addrmode6:$addr)))]>;
 
176
class VLD1Q<bits<4> op7_4, string OpcodeStr, string Dt,
 
177
            ValueType Ty, Intrinsic IntOp>
 
178
  : NLdSt<0,0b10,0b1010,op7_4, (outs QPR:$dst), (ins addrmode6:$addr), IIC_VLD1,
 
179
          OpcodeStr, Dt, "${dst:dregpair}, $addr", "",
 
180
          [(set QPR:$dst, (Ty (IntOp addrmode6:$addr)))]>;
 
181
 
 
182
def  VLD1d8   : VLD1D<0b0000, "vld1", "8",  v8i8,  int_arm_neon_vld1>;
 
183
def  VLD1d16  : VLD1D<0b0100, "vld1", "16", v4i16, int_arm_neon_vld1>;
 
184
def  VLD1d32  : VLD1D<0b1000, "vld1", "32", v2i32, int_arm_neon_vld1>;
 
185
def  VLD1df   : VLD1D<0b1000, "vld1", "32", v2f32, int_arm_neon_vld1>;
 
186
def  VLD1d64  : VLD1D<0b1100, "vld1", "64", v1i64, int_arm_neon_vld1>;
 
187
 
 
188
def  VLD1q8   : VLD1Q<0b0000, "vld1", "8",  v16i8, int_arm_neon_vld1>;
 
189
def  VLD1q16  : VLD1Q<0b0100, "vld1", "16", v8i16, int_arm_neon_vld1>;
 
190
def  VLD1q32  : VLD1Q<0b1000, "vld1", "32", v4i32, int_arm_neon_vld1>;
 
191
def  VLD1qf   : VLD1Q<0b1000, "vld1", "32", v4f32, int_arm_neon_vld1>;
 
192
def  VLD1q64  : VLD1Q<0b1100, "vld1", "64", v2i64, int_arm_neon_vld1>;
 
193
 
 
194
// These (dreg triple/quadruple) are for disassembly only.
 
195
class VLD1D3<bits<4> op7_4, string OpcodeStr, string Dt>
 
196
  : NLdSt<0, 0b10, 0b0110, op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
 
197
          (ins addrmode6:$addr), IIC_VLD1, OpcodeStr, Dt,
 
198
          "\\{$dst1, $dst2, $dst3\\}, $addr", "",
 
199
          [/* For disassembly only; pattern left blank */]>;
 
200
class VLD1D4<bits<4> op7_4, string OpcodeStr, string Dt>
 
201
  : NLdSt<0,0b10,0b0010,op7_4,(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 
202
          (ins addrmode6:$addr), IIC_VLD1, OpcodeStr, Dt,
 
203
          "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr", "",
 
204
          [/* For disassembly only; pattern left blank */]>;
 
205
 
 
206
def  VLD1d8T  : VLD1D3<0b0000, "vld1", "8">;
 
207
def  VLD1d16T : VLD1D3<0b0100, "vld1", "16">;
 
208
def  VLD1d32T : VLD1D3<0b1000, "vld1", "32">;
 
209
//def  VLD1d64T : VLD1D3<0b1100, "vld1", "64">;
 
210
 
 
211
def  VLD1d8Q  : VLD1D4<0b0000, "vld1", "8">;
 
212
def  VLD1d16Q : VLD1D4<0b0100, "vld1", "16">;
 
213
def  VLD1d32Q : VLD1D4<0b1000, "vld1", "32">;
 
214
//def  VLD1d64Q : VLD1D4<0b1100, "vld1", "64">;
 
215
 
 
216
 
 
217
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
 
218
 
 
219
//   VLD2     : Vector Load (multiple 2-element structures)
 
220
class VLD2D<bits<4> op7_4, string OpcodeStr, string Dt>
 
221
  : NLdSt<0,0b10,0b1000,op7_4, (outs DPR:$dst1, DPR:$dst2),
 
222
          (ins addrmode6:$addr), IIC_VLD2,
 
223
          OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
 
224
class VLD2Q<bits<4> op7_4, string OpcodeStr, string Dt>
 
225
  : NLdSt<0,0b10,0b0011,op7_4,
 
226
          (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 
227
          (ins addrmode6:$addr), IIC_VLD2,
 
228
          OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
 
229
          "", []>;
 
230
 
 
231
def  VLD2d8   : VLD2D<0b0000, "vld2", "8">;
 
232
def  VLD2d16  : VLD2D<0b0100, "vld2", "16">;
 
233
def  VLD2d32  : VLD2D<0b1000, "vld2", "32">;
 
234
def  VLD2d64  : NLdSt<0,0b10,0b1010,0b1100, (outs DPR:$dst1, DPR:$dst2),
 
235
                      (ins addrmode6:$addr), IIC_VLD1,
 
236
                      "vld1", "64", "\\{$dst1, $dst2\\}, $addr", "", []>;
 
237
 
 
238
def  VLD2q8   : VLD2Q<0b0000, "vld2", "8">;
 
239
def  VLD2q16  : VLD2Q<0b0100, "vld2", "16">;
 
240
def  VLD2q32  : VLD2Q<0b1000, "vld2", "32">;
 
241
 
 
242
// These (double-spaced dreg pair) are for disassembly only.
 
243
class VLD2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
 
244
  : NLdSt<0,0b10,0b1001,op7_4, (outs DPR:$dst1, DPR:$dst2),
 
245
          (ins addrmode6:$addr), IIC_VLD2,
 
246
          OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
 
247
 
 
248
def  VLD2d8D  : VLD2Ddbl<0b0000, "vld2", "8">;
 
249
def  VLD2d16D : VLD2Ddbl<0b0100, "vld2", "16">;
 
250
def  VLD2d32D : VLD2Ddbl<0b1000, "vld2", "32">;
 
251
 
 
252
//   VLD3     : Vector Load (multiple 3-element structures)
 
253
class VLD3D<bits<4> op7_4, string OpcodeStr, string Dt>
 
254
  : NLdSt<0,0b10,0b0100,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
 
255
          (ins addrmode6:$addr), IIC_VLD3,
 
256
          OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
 
257
class VLD3WB<bits<4> op7_4, string OpcodeStr, string Dt>
 
258
  : NLdSt<0,0b10,0b0101,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, GPR:$wb),
 
259
          (ins addrmode6:$addr), IIC_VLD3,
 
260
          OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr",
 
261
          "$addr.addr = $wb", []>;
 
262
 
 
263
def  VLD3d8   : VLD3D<0b0000, "vld3", "8">;
 
264
def  VLD3d16  : VLD3D<0b0100, "vld3", "16">;
 
265
def  VLD3d32  : VLD3D<0b1000, "vld3", "32">;
 
266
def  VLD3d64  : NLdSt<0,0b10,0b0110,0b1100,
 
267
                      (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
 
268
                      (ins addrmode6:$addr), IIC_VLD1,
 
269
                      "vld1", "64", "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
 
270
 
 
271
// vld3 to double-spaced even registers.
 
272
def  VLD3q8a  : VLD3WB<0b0000, "vld3", "8">;
 
273
def  VLD3q16a : VLD3WB<0b0100, "vld3", "16">;
 
274
def  VLD3q32a : VLD3WB<0b1000, "vld3", "32">;
 
275
 
 
276
// vld3 to double-spaced odd registers.
 
277
def  VLD3q8b  : VLD3WB<0b0000, "vld3", "8">;
 
278
def  VLD3q16b : VLD3WB<0b0100, "vld3", "16">;
 
279
def  VLD3q32b : VLD3WB<0b1000, "vld3", "32">;
 
280
 
 
281
//   VLD4     : Vector Load (multiple 4-element structures)
 
282
class VLD4D<bits<4> op7_4, string OpcodeStr, string Dt>
 
283
  : NLdSt<0,0b10,0b0000,op7_4,
 
284
          (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 
285
          (ins addrmode6:$addr), IIC_VLD4,
 
286
          OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
 
287
          "", []>;
 
288
class VLD4WB<bits<4> op7_4, string OpcodeStr, string Dt>
 
289
  : NLdSt<0,0b10,0b0001,op7_4,
 
290
          (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
 
291
          (ins addrmode6:$addr), IIC_VLD4,
 
292
          OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
 
293
          "$addr.addr = $wb", []>;
 
294
 
 
295
def  VLD4d8   : VLD4D<0b0000, "vld4", "8">;
 
296
def  VLD4d16  : VLD4D<0b0100, "vld4", "16">;
 
297
def  VLD4d32  : VLD4D<0b1000, "vld4", "32">;
 
298
def  VLD4d64  : NLdSt<0,0b10,0b0010,0b1100,
 
299
                      (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 
300
                      (ins addrmode6:$addr), IIC_VLD1,
 
301
                      "vld1", "64", "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
 
302
                      "", []>;
 
303
 
 
304
// vld4 to double-spaced even registers.
 
305
def  VLD4q8a  : VLD4WB<0b0000, "vld4", "8">;
 
306
def  VLD4q16a : VLD4WB<0b0100, "vld4", "16">;
 
307
def  VLD4q32a : VLD4WB<0b1000, "vld4", "32">;
 
308
 
 
309
// vld4 to double-spaced odd registers.
 
310
def  VLD4q8b  : VLD4WB<0b0000, "vld4", "8">;
 
311
def  VLD4q16b : VLD4WB<0b0100, "vld4", "16">;
 
312
def  VLD4q32b : VLD4WB<0b1000, "vld4", "32">;
 
313
 
 
314
//   VLD1LN   : Vector Load (single element to one lane)
 
315
//   FIXME: Not yet implemented.
 
316
 
 
317
//   VLD2LN   : Vector Load (single 2-element structure to one lane)
 
318
class VLD2LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
319
  : NLdSt<1,0b10,op11_8,{?,?,?,?}, (outs DPR:$dst1, DPR:$dst2),
 
320
            (ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
 
321
            IIC_VLD2, OpcodeStr, Dt, "\\{$dst1[$lane], $dst2[$lane]\\}, $addr",
 
322
            "$src1 = $dst1, $src2 = $dst2", []>;
 
323
 
 
324
// vld2 to single-spaced registers.
 
325
def VLD2LNd8  : VLD2LN<0b0001, "vld2", "8">;
 
326
def VLD2LNd16 : VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 0; }
 
327
def VLD2LNd32 : VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 0; }
 
328
 
 
329
// vld2 to double-spaced even registers.
 
330
def VLD2LNq16a: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
 
331
def VLD2LNq32a: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
 
332
 
 
333
// vld2 to double-spaced odd registers.
 
334
def VLD2LNq16b: VLD2LN<0b0101, "vld2", "16"> { let Inst{5} = 1; }
 
335
def VLD2LNq32b: VLD2LN<0b1001, "vld2", "32"> { let Inst{6} = 1; }
 
336
 
 
337
//   VLD3LN   : Vector Load (single 3-element structure to one lane)
 
338
class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
339
  : NLdSt<1,0b10,op11_8,{?,?,?,?}, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
 
340
            (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
 
341
            nohash_imm:$lane), IIC_VLD3, OpcodeStr, Dt,
 
342
            "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane]\\}, $addr",
 
343
            "$src1 = $dst1, $src2 = $dst2, $src3 = $dst3", []>;
 
344
 
 
345
// vld3 to single-spaced registers.
 
346
def VLD3LNd8  : VLD3LN<0b0010, "vld3", "8"> { let Inst{4} = 0; }
 
347
def VLD3LNd16 : VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b00; }
 
348
def VLD3LNd32 : VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b000; }
 
349
 
 
350
// vld3 to double-spaced even registers.
 
351
def VLD3LNq16a: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
 
352
def VLD3LNq32a: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
 
353
 
 
354
// vld3 to double-spaced odd registers.
 
355
def VLD3LNq16b: VLD3LN<0b0110, "vld3", "16"> { let Inst{5-4} = 0b10; }
 
356
def VLD3LNq32b: VLD3LN<0b1010, "vld3", "32"> { let Inst{6-4} = 0b100; }
 
357
 
 
358
//   VLD4LN   : Vector Load (single 4-element structure to one lane)
 
359
class VLD4LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
360
  : NLdSt<1,0b10,op11_8,{?,?,?,?},
 
361
            (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 
362
            (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
 
363
            nohash_imm:$lane), IIC_VLD4, OpcodeStr, Dt,
 
364
          "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $addr",
 
365
            "$src1 = $dst1, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>;
 
366
 
 
367
// vld4 to single-spaced registers.
 
368
def VLD4LNd8  : VLD4LN<0b0011, "vld4", "8">;
 
369
def VLD4LNd16 : VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 0; }
 
370
def VLD4LNd32 : VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 0; }
 
371
 
 
372
// vld4 to double-spaced even registers.
 
373
def VLD4LNq16a: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
 
374
def VLD4LNq32a: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
 
375
 
 
376
// vld4 to double-spaced odd registers.
 
377
def VLD4LNq16b: VLD4LN<0b0111, "vld4", "16"> { let Inst{5} = 1; }
 
378
def VLD4LNq32b: VLD4LN<0b1011, "vld4", "32"> { let Inst{6} = 1; }
 
379
 
 
380
//   VLD1DUP  : Vector Load (single element to all lanes)
 
381
//   VLD2DUP  : Vector Load (single 2-element structure to all lanes)
 
382
//   VLD3DUP  : Vector Load (single 3-element structure to all lanes)
 
383
//   VLD4DUP  : Vector Load (single 4-element structure to all lanes)
 
384
//   FIXME: Not yet implemented.
 
385
} // mayLoad = 1, hasExtraDefRegAllocReq = 1
 
386
 
 
387
//   VST1     : Vector Store (multiple single elements)
 
388
class VST1D<bits<4> op7_4, string OpcodeStr, string Dt,
 
389
            ValueType Ty, Intrinsic IntOp>
 
390
  : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins addrmode6:$addr, DPR:$src), IIC_VST,
 
391
          OpcodeStr, Dt, "\\{$src\\}, $addr", "",
 
392
          [(IntOp addrmode6:$addr, (Ty DPR:$src))]>;
 
393
class VST1Q<bits<4> op7_4, string OpcodeStr, string Dt,
 
394
            ValueType Ty, Intrinsic IntOp>
 
395
  : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins addrmode6:$addr, QPR:$src), IIC_VST,
 
396
          OpcodeStr, Dt, "${src:dregpair}, $addr", "",
 
397
          [(IntOp addrmode6:$addr, (Ty QPR:$src))]>;
 
398
 
 
399
let hasExtraSrcRegAllocReq = 1 in {
 
400
def  VST1d8   : VST1D<0b0000, "vst1", "8",  v8i8,  int_arm_neon_vst1>;
 
401
def  VST1d16  : VST1D<0b0100, "vst1", "16", v4i16, int_arm_neon_vst1>;
 
402
def  VST1d32  : VST1D<0b1000, "vst1", "32", v2i32, int_arm_neon_vst1>;
 
403
def  VST1df   : VST1D<0b1000, "vst1", "32", v2f32, int_arm_neon_vst1>;
 
404
def  VST1d64  : VST1D<0b1100, "vst1", "64", v1i64, int_arm_neon_vst1>;
 
405
 
 
406
def  VST1q8   : VST1Q<0b0000, "vst1", "8",  v16i8, int_arm_neon_vst1>;
 
407
def  VST1q16  : VST1Q<0b0100, "vst1", "16", v8i16, int_arm_neon_vst1>;
 
408
def  VST1q32  : VST1Q<0b1000, "vst1", "32", v4i32, int_arm_neon_vst1>;
 
409
def  VST1qf   : VST1Q<0b1000, "vst1", "32", v4f32, int_arm_neon_vst1>;
 
410
def  VST1q64  : VST1Q<0b1100, "vst1", "64", v2i64, int_arm_neon_vst1>;
 
411
} // hasExtraSrcRegAllocReq
 
412
 
 
413
// These (dreg triple/quadruple) are for disassembly only.
 
414
class VST1D3<bits<4> op7_4, string OpcodeStr, string Dt>
 
415
  : NLdSt<0, 0b00, 0b0110, op7_4, (outs),
 
416
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
 
417
          OpcodeStr, Dt,
 
418
          "\\{$src1, $src2, $src3\\}, $addr", "",
 
419
          [/* For disassembly only; pattern left blank */]>;
 
420
class VST1D4<bits<4> op7_4, string OpcodeStr, string Dt>
 
421
  : NLdSt<0, 0b00, 0b0010, op7_4, (outs),
 
422
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
 
423
          IIC_VST, OpcodeStr, Dt,
 
424
          "\\{$src1, $src2, $src3, $src4\\}, $addr", "",
 
425
          [/* For disassembly only; pattern left blank */]>;
 
426
 
 
427
def  VST1d8T  : VST1D3<0b0000, "vst1", "8">;
 
428
def  VST1d16T : VST1D3<0b0100, "vst1", "16">;
 
429
def  VST1d32T : VST1D3<0b1000, "vst1", "32">;
 
430
//def  VST1d64T : VST1D3<0b1100, "vst1", "64">;
 
431
 
 
432
def  VST1d8Q  : VST1D4<0b0000, "vst1", "8">;
 
433
def  VST1d16Q : VST1D4<0b0100, "vst1", "16">;
 
434
def  VST1d32Q : VST1D4<0b1000, "vst1", "32">;
 
435
//def  VST1d64Q : VST1D4<0b1100, "vst1", "64">;
 
436
 
 
437
 
 
438
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
 
439
 
 
440
//   VST2     : Vector Store (multiple 2-element structures)
 
441
class VST2D<bits<4> op7_4, string OpcodeStr, string Dt>
 
442
  : NLdSt<0,0b00,0b1000,op7_4, (outs),
 
443
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
 
444
          OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
 
445
class VST2Q<bits<4> op7_4, string OpcodeStr, string Dt>
 
446
  : NLdSt<0,0b00,0b0011,op7_4, (outs),
 
447
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
 
448
          IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
 
449
          "", []>;
 
450
 
 
451
def  VST2d8   : VST2D<0b0000, "vst2", "8">;
 
452
def  VST2d16  : VST2D<0b0100, "vst2", "16">;
 
453
def  VST2d32  : VST2D<0b1000, "vst2", "32">;
 
454
def  VST2d64  : NLdSt<0,0b00,0b1010,0b1100, (outs),
 
455
                      (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
 
456
                      "vst1", "64", "\\{$src1, $src2\\}, $addr", "", []>;
 
457
 
 
458
def  VST2q8   : VST2Q<0b0000, "vst2", "8">;
 
459
def  VST2q16  : VST2Q<0b0100, "vst2", "16">;
 
460
def  VST2q32  : VST2Q<0b1000, "vst2", "32">;
 
461
 
 
462
// These (double-spaced dreg pair) are for disassembly only.
 
463
class VST2Ddbl<bits<4> op7_4, string OpcodeStr, string Dt>
 
464
  : NLdSt<0, 0b00, 0b1001, op7_4, (outs),
 
465
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
 
466
          OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
 
467
 
 
468
def  VST2d8D  : VST2Ddbl<0b0000, "vst2", "8">;
 
469
def  VST2d16D : VST2Ddbl<0b0100, "vst2", "16">;
 
470
def  VST2d32D : VST2Ddbl<0b1000, "vst2", "32">;
 
471
 
 
472
//   VST3     : Vector Store (multiple 3-element structures)
 
473
class VST3D<bits<4> op7_4, string OpcodeStr, string Dt>
 
474
  : NLdSt<0,0b00,0b0100,op7_4, (outs),
 
475
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
 
476
          OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr", "", []>;
 
477
class VST3WB<bits<4> op7_4, string OpcodeStr, string Dt>
 
478
  : NLdSt<0,0b00,0b0101,op7_4, (outs GPR:$wb),
 
479
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
 
480
          OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr",
 
481
          "$addr.addr = $wb", []>;
 
482
 
 
483
def  VST3d8   : VST3D<0b0000, "vst3", "8">;
 
484
def  VST3d16  : VST3D<0b0100, "vst3", "16">;
 
485
def  VST3d32  : VST3D<0b1000, "vst3", "32">;
 
486
def  VST3d64  : NLdSt<0,0b00,0b0110,0b1100, (outs),
 
487
                      (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3),
 
488
                      IIC_VST,
 
489
                      "vst1", "64", "\\{$src1, $src2, $src3\\}, $addr", "", []>;
 
490
 
 
491
// vst3 to double-spaced even registers.
 
492
def  VST3q8a  : VST3WB<0b0000, "vst3", "8">;
 
493
def  VST3q16a : VST3WB<0b0100, "vst3", "16">;
 
494
def  VST3q32a : VST3WB<0b1000, "vst3", "32">;
 
495
 
 
496
// vst3 to double-spaced odd registers.
 
497
def  VST3q8b  : VST3WB<0b0000, "vst3", "8">;
 
498
def  VST3q16b : VST3WB<0b0100, "vst3", "16">;
 
499
def  VST3q32b : VST3WB<0b1000, "vst3", "32">;
 
500
 
 
501
//   VST4     : Vector Store (multiple 4-element structures)
 
502
class VST4D<bits<4> op7_4, string OpcodeStr, string Dt>
 
503
  : NLdSt<0,0b00,0b0000,op7_4, (outs),
 
504
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
 
505
          IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
 
506
          "", []>;
 
507
class VST4WB<bits<4> op7_4, string OpcodeStr, string Dt>
 
508
  : NLdSt<0,0b00,0b0001,op7_4, (outs GPR:$wb),
 
509
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
 
510
          IIC_VST, OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
 
511
          "$addr.addr = $wb", []>;
 
512
 
 
513
def  VST4d8   : VST4D<0b0000, "vst4", "8">;
 
514
def  VST4d16  : VST4D<0b0100, "vst4", "16">;
 
515
def  VST4d32  : VST4D<0b1000, "vst4", "32">;
 
516
def  VST4d64  : NLdSt<0,0b00,0b0010,0b1100, (outs),
 
517
                      (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
 
518
                       DPR:$src4), IIC_VST,
 
519
                      "vst1", "64", "\\{$src1, $src2, $src3, $src4\\}, $addr",
 
520
                      "", []>;
 
521
 
 
522
// vst4 to double-spaced even registers.
 
523
def  VST4q8a  : VST4WB<0b0000, "vst4", "8">;
 
524
def  VST4q16a : VST4WB<0b0100, "vst4", "16">;
 
525
def  VST4q32a : VST4WB<0b1000, "vst4", "32">;
 
526
 
 
527
// vst4 to double-spaced odd registers.
 
528
def  VST4q8b  : VST4WB<0b0000, "vst4", "8">;
 
529
def  VST4q16b : VST4WB<0b0100, "vst4", "16">;
 
530
def  VST4q32b : VST4WB<0b1000, "vst4", "32">;
 
531
 
 
532
//   VST1LN   : Vector Store (single element from one lane)
 
533
//   FIXME: Not yet implemented.
 
534
 
 
535
//   VST2LN   : Vector Store (single 2-element structure from one lane)
 
536
class VST2LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
537
  : NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
 
538
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
 
539
          IIC_VST, OpcodeStr, Dt, "\\{$src1[$lane], $src2[$lane]\\}, $addr",
 
540
          "", []>;
 
541
 
 
542
// vst2 to single-spaced registers.
 
543
def VST2LNd8  : VST2LN<0b0001, "vst2", "8">;
 
544
def VST2LNd16 : VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 0; }
 
545
def VST2LNd32 : VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 0; }
 
546
 
 
547
// vst2 to double-spaced even registers.
 
548
def VST2LNq16a: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
 
549
def VST2LNq32a: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
 
550
 
 
551
// vst2 to double-spaced odd registers.
 
552
def VST2LNq16b: VST2LN<0b0101, "vst2", "16"> { let Inst{5} = 1; }
 
553
def VST2LNq32b: VST2LN<0b1001, "vst2", "32"> { let Inst{6} = 1; }
 
554
 
 
555
//   VST3LN   : Vector Store (single 3-element structure from one lane)
 
556
class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
557
  : NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
 
558
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
 
559
           nohash_imm:$lane), IIC_VST, OpcodeStr, Dt,
 
560
          "\\{$src1[$lane], $src2[$lane], $src3[$lane]\\}, $addr", "", []>;
 
561
 
 
562
// vst3 to single-spaced registers.
 
563
def VST3LNd8  : VST3LN<0b0010, "vst3", "8"> { let Inst{4} = 0; }
 
564
def VST3LNd16 : VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b00; }
 
565
def VST3LNd32 : VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b000; }
 
566
 
 
567
// vst3 to double-spaced even registers.
 
568
def VST3LNq16a: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
 
569
def VST3LNq32a: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
 
570
 
 
571
// vst3 to double-spaced odd registers.
 
572
def VST3LNq16b: VST3LN<0b0110, "vst3", "16"> { let Inst{5-4} = 0b10; }
 
573
def VST3LNq32b: VST3LN<0b1010, "vst3", "32"> { let Inst{6-4} = 0b100; }
 
574
 
 
575
//   VST4LN   : Vector Store (single 4-element structure from one lane)
 
576
class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
 
577
  : NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
 
578
          (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
 
579
           nohash_imm:$lane), IIC_VST, OpcodeStr, Dt,
 
580
          "\\{$src1[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $addr",
 
581
          "", []>;
 
582
 
 
583
// vst4 to single-spaced registers.
 
584
def VST4LNd8  : VST4LN<0b0011, "vst4", "8">;
 
585
def VST4LNd16 : VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 0; }
 
586
def VST4LNd32 : VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 0; }
 
587
 
 
588
// vst4 to double-spaced even registers.
 
589
def VST4LNq16a: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
 
590
def VST4LNq32a: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
 
591
 
 
592
// vst4 to double-spaced odd registers.
 
593
def VST4LNq16b: VST4LN<0b0111, "vst4", "16"> { let Inst{5} = 1; }
 
594
def VST4LNq32b: VST4LN<0b1011, "vst4", "32"> { let Inst{6} = 1; }
 
595
 
 
596
} // mayStore = 1, hasExtraSrcRegAllocReq = 1
 
597
 
 
598
 
 
599
//===----------------------------------------------------------------------===//
 
600
// NEON pattern fragments
 
601
//===----------------------------------------------------------------------===//
 
602
 
 
603
// Extract D sub-registers of Q registers.
 
604
// (arm_dsubreg_0 is 5; arm_dsubreg_1 is 6)
 
605
def DSubReg_i8_reg  : SDNodeXForm<imm, [{
 
606
  return CurDAG->getTargetConstant(5 + N->getZExtValue() / 8, MVT::i32);
 
607
}]>;
 
608
def DSubReg_i16_reg : SDNodeXForm<imm, [{
 
609
  return CurDAG->getTargetConstant(5 + N->getZExtValue() / 4, MVT::i32);
 
610
}]>;
 
611
def DSubReg_i32_reg : SDNodeXForm<imm, [{
 
612
  return CurDAG->getTargetConstant(5 + N->getZExtValue() / 2, MVT::i32);
 
613
}]>;
 
614
def DSubReg_f64_reg : SDNodeXForm<imm, [{
 
615
  return CurDAG->getTargetConstant(5 + N->getZExtValue(), MVT::i32);
 
616
}]>;
 
617
def DSubReg_f64_other_reg : SDNodeXForm<imm, [{
 
618
  return CurDAG->getTargetConstant(5 + (1 - N->getZExtValue()), MVT::i32);
 
619
}]>;
 
620
 
 
621
// Extract S sub-registers of Q/D registers.
 
622
// (arm_ssubreg_0 is 1; arm_ssubreg_1 is 2; etc.)
 
623
def SSubReg_f32_reg : SDNodeXForm<imm, [{
 
624
  return CurDAG->getTargetConstant(1 + N->getZExtValue(), MVT::i32);
 
625
}]>;
 
626
 
 
627
// Translate lane numbers from Q registers to D subregs.
 
628
def SubReg_i8_lane  : SDNodeXForm<imm, [{
 
629
  return CurDAG->getTargetConstant(N->getZExtValue() & 7, MVT::i32);
 
630
}]>;
 
631
def SubReg_i16_lane : SDNodeXForm<imm, [{
 
632
  return CurDAG->getTargetConstant(N->getZExtValue() & 3, MVT::i32);
 
633
}]>;
 
634
def SubReg_i32_lane : SDNodeXForm<imm, [{
 
635
  return CurDAG->getTargetConstant(N->getZExtValue() & 1, MVT::i32);
 
636
}]>;
 
637
 
 
638
//===----------------------------------------------------------------------===//
 
639
// Instruction Classes
 
640
//===----------------------------------------------------------------------===//
 
641
 
 
642
// Basic 2-register operations: single-, double- and quad-register.
 
643
class N2VS<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
644
           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 
645
           string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
 
646
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
 
647
        (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src),
 
648
        IIC_VUNAD, OpcodeStr, Dt, "$dst, $src", "", []>;
 
649
class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
650
           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 
651
           string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
 
652
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 
653
        (ins DPR:$src), IIC_VUNAD, OpcodeStr, Dt, "$dst, $src", "",
 
654
        [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src))))]>;
 
655
class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
656
           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 
657
           string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode>
 
658
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 
659
        (ins QPR:$src), IIC_VUNAQ, OpcodeStr, Dt, "$dst, $src", "",
 
660
        [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src))))]>;
 
661
 
 
662
// Basic 2-register intrinsics, both double- and quad-register.
 
663
class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
664
              bits<2> op17_16, bits<5> op11_7, bit op4, 
 
665
              InstrItinClass itin, string OpcodeStr, string Dt,
 
666
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
667
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 
668
        (ins DPR:$src), itin, OpcodeStr, Dt, "$dst, $src", "",
 
669
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>;
 
670
class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
671
              bits<2> op17_16, bits<5> op11_7, bit op4,
 
672
              InstrItinClass itin, string OpcodeStr, string Dt,
 
673
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
674
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 
675
        (ins QPR:$src), itin, OpcodeStr, Dt, "$dst, $src", "",
 
676
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>;
 
677
 
 
678
// Narrow 2-register intrinsics.
 
679
class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
680
              bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
 
681
              InstrItinClass itin, string OpcodeStr, string Dt,
 
682
              ValueType TyD, ValueType TyQ, Intrinsic IntOp>
 
683
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$dst),
 
684
        (ins QPR:$src), itin, OpcodeStr, Dt, "$dst, $src", "",
 
685
        [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src))))]>;
 
686
 
 
687
// Long 2-register intrinsics (currently only used for VMOVL).
 
688
class N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
689
              bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
 
690
              InstrItinClass itin, string OpcodeStr, string Dt,
 
691
              ValueType TyQ, ValueType TyD, Intrinsic IntOp>
 
692
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$dst),
 
693
        (ins DPR:$src), itin, OpcodeStr, Dt, "$dst, $src", "",
 
694
        [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src))))]>;
 
695
 
 
696
// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register.
 
697
class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt>
 
698
  : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$dst1, DPR:$dst2),
 
699
        (ins DPR:$src1, DPR:$src2), IIC_VPERMD, 
 
700
        OpcodeStr, Dt, "$dst1, $dst2",
 
701
        "$src1 = $dst1, $src2 = $dst2", []>;
 
702
class N2VQShuffle<bits<2> op19_18, bits<5> op11_7,
 
703
                  InstrItinClass itin, string OpcodeStr, string Dt>
 
704
  : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$dst1, QPR:$dst2),
 
705
        (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$dst1, $dst2",
 
706
        "$src1 = $dst1, $src2 = $dst2", []>;
 
707
 
 
708
// Basic 3-register operations: single-, double- and quad-register.
 
709
class N3VS<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
710
           string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
 
711
           SDNode OpNode, bit Commutable>
 
712
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
713
        (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
 
714
        OpcodeStr, Dt, "$dst, $src1, $src2", "", []> {
 
715
  let isCommutable = Commutable;
 
716
}
 
717
 
 
718
class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
719
           InstrItinClass itin, string OpcodeStr, string Dt,
 
720
           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
 
721
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
722
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin, 
 
723
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
724
        [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]> {
 
725
  let isCommutable = Commutable;
 
726
}
 
727
// Same as N3VD but no data type.
 
728
class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
729
           InstrItinClass itin, string OpcodeStr,
 
730
           ValueType ResTy, ValueType OpTy,
 
731
           SDNode OpNode, bit Commutable>
 
732
  : N3VX<op24, op23, op21_20, op11_8, 0, op4,
 
733
         (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin, 
 
734
         OpcodeStr, "$dst, $src1, $src2", "",
 
735
         [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]>{
 
736
  let isCommutable = Commutable;
 
737
}
 
738
class N3VDSL<bits<2> op21_20, bits<4> op11_8, 
 
739
             InstrItinClass itin, string OpcodeStr, string Dt,
 
740
             ValueType Ty, SDNode ShOp>
 
741
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
742
        (outs DPR:$dst), (ins DPR:$src1, DPR_VFP2:$src2, nohash_imm:$lane),
 
743
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
744
        [(set (Ty DPR:$dst),
 
745
              (Ty (ShOp (Ty DPR:$src1),
 
746
                        (Ty (NEONvduplane (Ty DPR_VFP2:$src2), imm:$lane)))))]>{
 
747
  let isCommutable = 0;
 
748
}
 
749
class N3VDSL16<bits<2> op21_20, bits<4> op11_8, 
 
750
               string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
 
751
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
752
        (outs DPR:$dst), (ins DPR:$src1, DPR_8:$src2, nohash_imm:$lane),
 
753
        IIC_VMULi16D, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
754
        [(set (Ty DPR:$dst),
 
755
              (Ty (ShOp (Ty DPR:$src1),
 
756
                        (Ty (NEONvduplane (Ty DPR_8:$src2), imm:$lane)))))]> {
 
757
  let isCommutable = 0;
 
758
}
 
759
 
 
760
class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
761
           InstrItinClass itin, string OpcodeStr, string Dt,
 
762
           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
 
763
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 
764
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin, 
 
765
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
766
        [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]> {
 
767
  let isCommutable = Commutable;
 
768
}
 
769
class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
770
           InstrItinClass itin, string OpcodeStr,
 
771
           ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable>
 
772
  : N3VX<op24, op23, op21_20, op11_8, 1, op4,
 
773
         (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin, 
 
774
         OpcodeStr, "$dst, $src1, $src2", "",
 
775
         [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]>{
 
776
  let isCommutable = Commutable;
 
777
}
 
778
class N3VQSL<bits<2> op21_20, bits<4> op11_8, 
 
779
             InstrItinClass itin, string OpcodeStr, string Dt,
 
780
             ValueType ResTy, ValueType OpTy, SDNode ShOp>
 
781
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
782
        (outs QPR:$dst), (ins QPR:$src1, DPR_VFP2:$src2, nohash_imm:$lane),
 
783
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
784
        [(set (ResTy QPR:$dst),
 
785
              (ResTy (ShOp (ResTy QPR:$src1),
 
786
                           (ResTy (NEONvduplane (OpTy DPR_VFP2:$src2),
 
787
                                                imm:$lane)))))]> {
 
788
  let isCommutable = 0;
 
789
}
 
790
class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
 
791
               ValueType ResTy, ValueType OpTy, SDNode ShOp>
 
792
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
793
        (outs QPR:$dst), (ins QPR:$src1, DPR_8:$src2, nohash_imm:$lane),
 
794
        IIC_VMULi16Q, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
795
        [(set (ResTy QPR:$dst),
 
796
              (ResTy (ShOp (ResTy QPR:$src1),
 
797
                           (ResTy (NEONvduplane (OpTy DPR_8:$src2),
 
798
                                                imm:$lane)))))]> {
 
799
  let isCommutable = 0;
 
800
}
 
801
 
 
802
// Basic 3-register intrinsics, both double- and quad-register.
 
803
class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
804
              InstrItinClass itin, string OpcodeStr, string Dt,
 
805
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable>
 
806
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
807
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), itin, 
 
808
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
809
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1), (OpTy DPR:$src2))))]> {
 
810
  let isCommutable = Commutable;
 
811
}
 
812
class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 
 
813
                string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
 
814
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
815
        (outs DPR:$dst), (ins DPR:$src1, DPR_VFP2:$src2, nohash_imm:$lane),
 
816
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
817
        [(set (Ty DPR:$dst),
 
818
              (Ty (IntOp (Ty DPR:$src1),
 
819
                         (Ty (NEONvduplane (Ty DPR_VFP2:$src2),
 
820
                                           imm:$lane)))))]> {
 
821
  let isCommutable = 0;
 
822
}
 
823
class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
824
                  string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
 
825
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
826
        (outs DPR:$dst), (ins DPR:$src1, DPR_8:$src2, nohash_imm:$lane),
 
827
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
828
        [(set (Ty DPR:$dst),
 
829
              (Ty (IntOp (Ty DPR:$src1),
 
830
                         (Ty (NEONvduplane (Ty DPR_8:$src2),
 
831
                                           imm:$lane)))))]> {
 
832
  let isCommutable = 0;
 
833
}
 
834
 
 
835
class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
836
              InstrItinClass itin, string OpcodeStr, string Dt,
 
837
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable>
 
838
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 
839
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), itin, 
 
840
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
841
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1), (OpTy QPR:$src2))))]> {
 
842
  let isCommutable = Commutable;
 
843
}
 
844
class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 
 
845
                string OpcodeStr, string Dt,
 
846
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
847
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
848
        (outs QPR:$dst), (ins QPR:$src1, DPR_VFP2:$src2, nohash_imm:$lane),
 
849
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
850
        [(set (ResTy QPR:$dst),
 
851
              (ResTy (IntOp (ResTy QPR:$src1),
 
852
                            (ResTy (NEONvduplane (OpTy DPR_VFP2:$src2),
 
853
                                                 imm:$lane)))))]> {
 
854
  let isCommutable = 0;
 
855
}
 
856
class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
857
                  string OpcodeStr, string Dt,
 
858
                  ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
859
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
860
        (outs QPR:$dst), (ins QPR:$src1, DPR_8:$src2, nohash_imm:$lane),
 
861
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
862
        [(set (ResTy QPR:$dst),
 
863
              (ResTy (IntOp (ResTy QPR:$src1),
 
864
                            (ResTy (NEONvduplane (OpTy DPR_8:$src2),
 
865
                                                 imm:$lane)))))]> {
 
866
  let isCommutable = 0;
 
867
}
 
868
 
 
869
// Multiply-Add/Sub operations: single-, double- and quad-register.
 
870
class N3VSMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
871
                InstrItinClass itin, string OpcodeStr, string Dt,
 
872
                ValueType Ty, SDNode MulOp, SDNode OpNode>
 
873
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
874
        (outs DPR_VFP2:$dst),
 
875
        (ins DPR_VFP2:$src1, DPR_VFP2:$src2, DPR_VFP2:$src3), itin,
 
876
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst", []>;
 
877
 
 
878
class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
879
                InstrItinClass itin, string OpcodeStr, string Dt,
 
880
                ValueType Ty, SDNode MulOp, SDNode OpNode>
 
881
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
882
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), itin,
 
883
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst",
 
884
        [(set DPR:$dst, (Ty (OpNode DPR:$src1,
 
885
                             (Ty (MulOp DPR:$src2, DPR:$src3)))))]>;
 
886
class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
887
                  string OpcodeStr, string Dt,
 
888
                  ValueType Ty, SDNode MulOp, SDNode ShOp>
 
889
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
890
        (outs DPR:$dst),
 
891
        (ins DPR:$src1, DPR:$src2, DPR_VFP2:$src3, nohash_imm:$lane), itin,
 
892
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
893
        [(set (Ty DPR:$dst),
 
894
              (Ty (ShOp (Ty DPR:$src1),
 
895
                        (Ty (MulOp DPR:$src2,
 
896
                                   (Ty (NEONvduplane (Ty DPR_VFP2:$src3),
 
897
                                                     imm:$lane)))))))]>;
 
898
class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
899
                    string OpcodeStr, string Dt,
 
900
                    ValueType Ty, SDNode MulOp, SDNode ShOp>
 
901
  : N3V<0, 1, op21_20, op11_8, 1, 0,
 
902
        (outs DPR:$dst),
 
903
        (ins DPR:$src1, DPR:$src2, DPR_8:$src3, nohash_imm:$lane), itin,
 
904
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
905
        [(set (Ty DPR:$dst),
 
906
              (Ty (ShOp (Ty DPR:$src1),
 
907
                        (Ty (MulOp DPR:$src2,
 
908
                                   (Ty (NEONvduplane (Ty DPR_8:$src3),
 
909
                                                     imm:$lane)))))))]>;
 
910
 
 
911
class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
912
                InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty,
 
913
                SDNode MulOp, SDNode OpNode>
 
914
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 
915
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), itin,
 
916
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst",
 
917
        [(set QPR:$dst, (Ty (OpNode QPR:$src1,
 
918
                             (Ty (MulOp QPR:$src2, QPR:$src3)))))]>;
 
919
class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
920
                  string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
 
921
                  SDNode MulOp, SDNode ShOp>
 
922
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
923
        (outs QPR:$dst),
 
924
        (ins QPR:$src1, QPR:$src2, DPR_VFP2:$src3, nohash_imm:$lane), itin,
 
925
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
926
        [(set (ResTy QPR:$dst),
 
927
              (ResTy (ShOp (ResTy QPR:$src1),
 
928
                           (ResTy (MulOp QPR:$src2,
 
929
                                   (ResTy (NEONvduplane (OpTy DPR_VFP2:$src3),
 
930
                                                        imm:$lane)))))))]>;
 
931
class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
932
                    string OpcodeStr, string Dt,
 
933
                    ValueType ResTy, ValueType OpTy,
 
934
                    SDNode MulOp, SDNode ShOp>
 
935
  : N3V<1, 1, op21_20, op11_8, 1, 0,
 
936
        (outs QPR:$dst),
 
937
        (ins QPR:$src1, QPR:$src2, DPR_8:$src3, nohash_imm:$lane), itin,
 
938
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
939
        [(set (ResTy QPR:$dst),
 
940
              (ResTy (ShOp (ResTy QPR:$src1),
 
941
                           (ResTy (MulOp QPR:$src2,
 
942
                                   (ResTy (NEONvduplane (OpTy DPR_8:$src3),
 
943
                                                        imm:$lane)))))))]>;
 
944
 
 
945
// Neon 3-argument intrinsics, both double- and quad-register.
 
946
// The destination register is also used as the first source operand register.
 
947
class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
948
               InstrItinClass itin, string OpcodeStr, string Dt,
 
949
               ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
950
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
951
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), itin,
 
952
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst",
 
953
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1),
 
954
                                      (OpTy DPR:$src2), (OpTy DPR:$src3))))]>;
 
955
class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
956
               InstrItinClass itin, string OpcodeStr, string Dt,
 
957
               ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
958
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 
959
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), itin,
 
960
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst",
 
961
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1),
 
962
                                      (OpTy QPR:$src2), (OpTy QPR:$src3))))]>;
 
963
 
 
964
// Neon Long 3-argument intrinsic.  The destination register is
 
965
// a quad-register and is also used as the first source operand register.
 
966
class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
967
               InstrItinClass itin, string OpcodeStr, string Dt,
 
968
               ValueType TyQ, ValueType TyD, Intrinsic IntOp>
 
969
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
970
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2, DPR:$src3), itin,
 
971
        OpcodeStr, Dt, "$dst, $src2, $src3", "$src1 = $dst",
 
972
        [(set QPR:$dst,
 
973
          (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2), (TyD DPR:$src3))))]>;
 
974
class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
975
                 string OpcodeStr, string Dt,
 
976
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
977
  : N3V<op24, 1, op21_20, op11_8, 1, 0,
 
978
        (outs QPR:$dst),
 
979
        (ins QPR:$src1, DPR:$src2, DPR_VFP2:$src3, nohash_imm:$lane), itin,
 
980
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
981
        [(set (ResTy QPR:$dst),
 
982
              (ResTy (IntOp (ResTy QPR:$src1),
 
983
                            (OpTy DPR:$src2),
 
984
                            (OpTy (NEONvduplane (OpTy DPR_VFP2:$src3),
 
985
                                                imm:$lane)))))]>;
 
986
class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
 
987
                   InstrItinClass itin, string OpcodeStr, string Dt,
 
988
                   ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
989
  : N3V<op24, 1, op21_20, op11_8, 1, 0,
 
990
        (outs QPR:$dst),
 
991
        (ins QPR:$src1, DPR:$src2, DPR_8:$src3, nohash_imm:$lane), itin,
 
992
        OpcodeStr, Dt, "$dst, $src2, $src3[$lane]", "$src1 = $dst",
 
993
        [(set (ResTy QPR:$dst),
 
994
              (ResTy (IntOp (ResTy QPR:$src1),
 
995
                            (OpTy DPR:$src2),
 
996
                            (OpTy (NEONvduplane (OpTy DPR_8:$src3),
 
997
                                                imm:$lane)))))]>;
 
998
 
 
999
// Narrowing 3-register intrinsics.
 
1000
class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
1001
              string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ,
 
1002
              Intrinsic IntOp, bit Commutable>
 
1003
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
1004
        (outs DPR:$dst), (ins QPR:$src1, QPR:$src2), IIC_VBINi4D,
 
1005
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
1006
        [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src1), (TyQ QPR:$src2))))]> {
 
1007
  let isCommutable = Commutable;
 
1008
}
 
1009
 
 
1010
// Long 3-register intrinsics.
 
1011
class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
1012
              InstrItinClass itin, string OpcodeStr, string Dt,
 
1013
              ValueType TyQ, ValueType TyD, Intrinsic IntOp, bit Commutable>
 
1014
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
1015
        (outs QPR:$dst), (ins DPR:$src1, DPR:$src2), itin,
 
1016
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
1017
        [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src1), (TyD DPR:$src2))))]> {
 
1018
  let isCommutable = Commutable;
 
1019
}
 
1020
class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 
1021
                string OpcodeStr, string Dt,
 
1022
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1023
  : N3V<op24, 1, op21_20, op11_8, 1, 0,
 
1024
        (outs QPR:$dst), (ins DPR:$src1, DPR_VFP2:$src2, nohash_imm:$lane), 
 
1025
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
1026
        [(set (ResTy QPR:$dst),
 
1027
              (ResTy (IntOp (OpTy DPR:$src1),
 
1028
                            (OpTy (NEONvduplane (OpTy DPR_VFP2:$src2),
 
1029
                                                imm:$lane)))))]>;
 
1030
class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
 
1031
                  InstrItinClass itin, string OpcodeStr, string Dt,
 
1032
                  ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1033
  : N3V<op24, 1, op21_20, op11_8, 1, 0,
 
1034
        (outs QPR:$dst), (ins DPR:$src1, DPR_8:$src2, nohash_imm:$lane), 
 
1035
        itin, OpcodeStr, Dt, "$dst, $src1, $src2[$lane]", "",
 
1036
        [(set (ResTy QPR:$dst),
 
1037
              (ResTy (IntOp (OpTy DPR:$src1),
 
1038
                            (OpTy (NEONvduplane (OpTy DPR_8:$src2),
 
1039
                                                imm:$lane)))))]>;
 
1040
 
 
1041
// Wide 3-register intrinsics.
 
1042
class N3VWInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 
1043
              string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD,
 
1044
              Intrinsic IntOp, bit Commutable>
 
1045
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 
1046
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2), IIC_VSUBiD,
 
1047
        OpcodeStr, Dt, "$dst, $src1, $src2", "",
 
1048
        [(set QPR:$dst, (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2))))]> {
 
1049
  let isCommutable = Commutable;
 
1050
}
 
1051
 
 
1052
// Pairwise long 2-register intrinsics, both double- and quad-register.
 
1053
class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
1054
                bits<2> op17_16, bits<5> op11_7, bit op4,
 
1055
                string OpcodeStr, string Dt,
 
1056
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1057
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 
1058
        (ins DPR:$src), IIC_VSHLiD, OpcodeStr, Dt, "$dst, $src", "",
 
1059
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>;
 
1060
class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
1061
                bits<2> op17_16, bits<5> op11_7, bit op4,
 
1062
                string OpcodeStr, string Dt,
 
1063
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1064
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 
1065
        (ins QPR:$src), IIC_VSHLiD, OpcodeStr, Dt, "$dst, $src", "",
 
1066
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>;
 
1067
 
 
1068
// Pairwise long 2-register accumulate intrinsics,
 
1069
// both double- and quad-register.
 
1070
// The destination register is also used as the first source operand register.
 
1071
class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
1072
                 bits<2> op17_16, bits<5> op11_7, bit op4,
 
1073
                 string OpcodeStr, string Dt,
 
1074
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1075
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
 
1076
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), IIC_VPALiD,
 
1077
        OpcodeStr, Dt, "$dst, $src2", "$src1 = $dst",
 
1078
        [(set DPR:$dst, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$src2))))]>;
 
1079
class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 
1080
                 bits<2> op17_16, bits<5> op11_7, bit op4,
 
1081
                 string OpcodeStr, string Dt,
 
1082
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 
1083
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4,
 
1084
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), IIC_VPALiQ,
 
1085
        OpcodeStr, Dt, "$dst, $src2", "$src1 = $dst",
 
1086
        [(set QPR:$dst, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$src2))))]>;
 
1087
 
 
1088
// Shift by immediate,
 
1089
// both double- and quad-register.
 
1090
class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1091
             InstrItinClass itin, string OpcodeStr, string Dt,
 
1092
             ValueType Ty, SDNode OpNode>
 
1093
  : N2VImm<op24, op23, op11_8, op7, 0, op4,
 
1094
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), itin,
 
1095
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1096
           [(set DPR:$dst, (Ty (OpNode (Ty DPR:$src), (i32 imm:$SIMM))))]>;
 
1097
class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1098
             InstrItinClass itin, string OpcodeStr, string Dt,
 
1099
             ValueType Ty, SDNode OpNode>
 
1100
  : N2VImm<op24, op23, op11_8, op7, 1, op4,
 
1101
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), itin,
 
1102
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1103
           [(set QPR:$dst, (Ty (OpNode (Ty QPR:$src), (i32 imm:$SIMM))))]>;
 
1104
 
 
1105
// Long shift by immediate.
 
1106
class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
 
1107
             string OpcodeStr, string Dt,
 
1108
             ValueType ResTy, ValueType OpTy, SDNode OpNode>
 
1109
  : N2VImm<op24, op23, op11_8, op7, op6, op4,
 
1110
           (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM), IIC_VSHLiD,
 
1111
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1112
           [(set QPR:$dst, (ResTy (OpNode (OpTy DPR:$src),
 
1113
                                          (i32 imm:$SIMM))))]>;
 
1114
 
 
1115
// Narrow shift by immediate.
 
1116
class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
 
1117
             InstrItinClass itin, string OpcodeStr, string Dt,
 
1118
             ValueType ResTy, ValueType OpTy, SDNode OpNode>
 
1119
  : N2VImm<op24, op23, op11_8, op7, op6, op4,
 
1120
           (outs DPR:$dst), (ins QPR:$src, i32imm:$SIMM), itin,
 
1121
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1122
           [(set DPR:$dst, (ResTy (OpNode (OpTy QPR:$src),
 
1123
                                          (i32 imm:$SIMM))))]>;
 
1124
 
 
1125
// Shift right by immediate and accumulate,
 
1126
// both double- and quad-register.
 
1127
class N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1128
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
 
1129
  : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$dst),
 
1130
           (ins DPR:$src1, DPR:$src2, i32imm:$SIMM), IIC_VPALiD, 
 
1131
           OpcodeStr, Dt, "$dst, $src2, $SIMM", "$src1 = $dst",
 
1132
           [(set DPR:$dst, (Ty (add DPR:$src1,
 
1133
                                (Ty (ShOp DPR:$src2, (i32 imm:$SIMM))))))]>;
 
1134
class N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1135
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
 
1136
  : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$dst),
 
1137
           (ins QPR:$src1, QPR:$src2, i32imm:$SIMM), IIC_VPALiD, 
 
1138
           OpcodeStr, Dt, "$dst, $src2, $SIMM", "$src1 = $dst",
 
1139
           [(set QPR:$dst, (Ty (add QPR:$src1,
 
1140
                                (Ty (ShOp QPR:$src2, (i32 imm:$SIMM))))))]>;
 
1141
 
 
1142
// Shift by immediate and insert,
 
1143
// both double- and quad-register.
 
1144
class N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1145
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
 
1146
  : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$dst),
 
1147
           (ins DPR:$src1, DPR:$src2, i32imm:$SIMM), IIC_VSHLiD, 
 
1148
           OpcodeStr, Dt, "$dst, $src2, $SIMM", "$src1 = $dst",
 
1149
           [(set DPR:$dst, (Ty (ShOp DPR:$src1, DPR:$src2, (i32 imm:$SIMM))))]>;
 
1150
class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1151
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
 
1152
  : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$dst),
 
1153
           (ins QPR:$src1, QPR:$src2, i32imm:$SIMM), IIC_VSHLiQ, 
 
1154
           OpcodeStr, Dt, "$dst, $src2, $SIMM", "$src1 = $dst",
 
1155
           [(set QPR:$dst, (Ty (ShOp QPR:$src1, QPR:$src2, (i32 imm:$SIMM))))]>;
 
1156
 
 
1157
// Convert, with fractional bits immediate,
 
1158
// both double- and quad-register.
 
1159
class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1160
              string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
 
1161
              Intrinsic IntOp>
 
1162
  : N2VImm<op24, op23, op11_8, op7, 0, op4,
 
1163
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), IIC_VUNAD, 
 
1164
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1165
           [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src), (i32 imm:$SIMM))))]>;
 
1166
class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4,
 
1167
              string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
 
1168
              Intrinsic IntOp>
 
1169
  : N2VImm<op24, op23, op11_8, op7, 1, op4,
 
1170
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), IIC_VUNAQ, 
 
1171
           OpcodeStr, Dt, "$dst, $src, $SIMM", "",
 
1172
           [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src), (i32 imm:$SIMM))))]>;
 
1173
 
 
1174
//===----------------------------------------------------------------------===//
 
1175
// Multiclasses
 
1176
//===----------------------------------------------------------------------===//
 
1177
 
 
1178
// Abbreviations used in multiclass suffixes:
 
1179
//   Q = quarter int (8 bit) elements
 
1180
//   H = half int (16 bit) elements
 
1181
//   S = single int (32 bit) elements
 
1182
//   D = double int (64 bit) elements
 
1183
 
 
1184
// Neon 2-register vector operations -- for disassembly only.
 
1185
 
 
1186
// First with only element sizes of 8, 16 and 32 bits:
 
1187
multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
 
1188
                       bits<5> op11_7, bit op4, string opc, string Dt,
 
1189
                       string asm> {
 
1190
  // 64-bit vector types.
 
1191
  def v8i8  : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4,
 
1192
                  (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 
1193
                  opc, !strconcat(Dt, "8"), asm, "", []>;
 
1194
  def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4,
 
1195
                  (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 
1196
                  opc, !strconcat(Dt, "16"), asm, "", []>;
 
1197
  def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
 
1198
                  (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 
1199
                  opc, !strconcat(Dt, "32"), asm, "", []>;
 
1200
  def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4,
 
1201
                  (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 
1202
                  opc, "f32", asm, "", []> {
 
1203
    let Inst{10} = 1; // overwrite F = 1
 
1204
  }
 
1205
 
 
1206
  // 128-bit vector types.
 
1207
  def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4,
 
1208
                  (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 
1209
                  opc, !strconcat(Dt, "8"), asm, "", []>;
 
1210
  def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4,
 
1211
                  (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 
1212
                  opc, !strconcat(Dt, "16"), asm, "", []>;
 
1213
  def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
 
1214
                  (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 
1215
                  opc, !strconcat(Dt, "32"), asm, "", []>;
 
1216
  def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4,
 
1217
                  (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 
1218
                  opc, "f32", asm, "", []> {
 
1219
    let Inst{10} = 1; // overwrite F = 1
 
1220
  }
 
1221
}
 
1222
 
 
1223
// Neon 3-register vector operations.
 
1224
 
 
1225
// First with only element sizes of 8, 16 and 32 bits:
 
1226
multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1227
                   InstrItinClass itinD16, InstrItinClass itinD32,
 
1228
                   InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1229
                   string OpcodeStr, string Dt,
 
1230
                   SDNode OpNode, bit Commutable = 0> {
 
1231
  // 64-bit vector types.
 
1232
  def v8i8  : N3VD<op24, op23, 0b00, op11_8, op4, itinD16, 
 
1233
                   OpcodeStr, !strconcat(Dt, "8"),
 
1234
                   v8i8, v8i8, OpNode, Commutable>;
 
1235
  def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16,
 
1236
                   OpcodeStr, !strconcat(Dt, "16"),
 
1237
                   v4i16, v4i16, OpNode, Commutable>;
 
1238
  def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32,
 
1239
                   OpcodeStr, !strconcat(Dt, "32"),
 
1240
                   v2i32, v2i32, OpNode, Commutable>;
 
1241
 
 
1242
  // 128-bit vector types.
 
1243
  def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16,
 
1244
                   OpcodeStr, !strconcat(Dt, "8"),
 
1245
                   v16i8, v16i8, OpNode, Commutable>;
 
1246
  def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16,
 
1247
                   OpcodeStr, !strconcat(Dt, "16"),
 
1248
                   v8i16, v8i16, OpNode, Commutable>;
 
1249
  def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32,
 
1250
                   OpcodeStr, !strconcat(Dt, "32"),
 
1251
                   v4i32, v4i32, OpNode, Commutable>;
 
1252
}
 
1253
 
 
1254
multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, string Dt, SDNode ShOp> {
 
1255
  def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, !strconcat(Dt, "16"),
 
1256
                       v4i16, ShOp>;
 
1257
  def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, !strconcat(Dt,"32"),
 
1258
                     v2i32, ShOp>;
 
1259
  def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, !strconcat(Dt, "16"),
 
1260
                       v8i16, v4i16, ShOp>;
 
1261
  def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, !strconcat(Dt,"32"),
 
1262
                     v4i32, v2i32, ShOp>;
 
1263
}
 
1264
 
 
1265
// ....then also with element size 64 bits:
 
1266
multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1267
                    InstrItinClass itinD, InstrItinClass itinQ,
 
1268
                    string OpcodeStr, string Dt,
 
1269
                    SDNode OpNode, bit Commutable = 0>
 
1270
  : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ,
 
1271
            OpcodeStr, Dt, OpNode, Commutable> {
 
1272
  def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD,
 
1273
                   OpcodeStr, !strconcat(Dt, "64"),
 
1274
                   v1i64, v1i64, OpNode, Commutable>;
 
1275
  def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ,
 
1276
                   OpcodeStr, !strconcat(Dt, "64"),
 
1277
                   v2i64, v2i64, OpNode, Commutable>;
 
1278
}
 
1279
 
 
1280
 
 
1281
// Neon Narrowing 2-register vector intrinsics,
 
1282
//   source operand element sizes of 16, 32 and 64 bits:
 
1283
multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
 
1284
                       bits<5> op11_7, bit op6, bit op4, 
 
1285
                       InstrItinClass itin, string OpcodeStr, string Dt,
 
1286
                       Intrinsic IntOp> {
 
1287
  def v8i8  : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4,
 
1288
                      itin, OpcodeStr, !strconcat(Dt, "16"),
 
1289
                      v8i8, v8i16, IntOp>;
 
1290
  def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4,
 
1291
                      itin, OpcodeStr, !strconcat(Dt, "32"),
 
1292
                      v4i16, v4i32, IntOp>;
 
1293
  def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4,
 
1294
                      itin, OpcodeStr, !strconcat(Dt, "64"),
 
1295
                      v2i32, v2i64, IntOp>;
 
1296
}
 
1297
 
 
1298
 
 
1299
// Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL).
 
1300
//   source operand element sizes of 16, 32 and 64 bits:
 
1301
multiclass N2VLInt_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4,
 
1302
                       string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1303
  def v8i16 : N2VLInt<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
 
1304
                      OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>;
 
1305
  def v4i32 : N2VLInt<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
 
1306
                      OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
 
1307
  def v2i64 : N2VLInt<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD,
 
1308
                      OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
 
1309
}
 
1310
 
 
1311
 
 
1312
// Neon 3-register vector intrinsics.
 
1313
 
 
1314
// First with only element sizes of 16 and 32 bits:
 
1315
multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1316
                     InstrItinClass itinD16, InstrItinClass itinD32,
 
1317
                     InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1318
                     string OpcodeStr, string Dt,
 
1319
                     Intrinsic IntOp, bit Commutable = 0> {
 
1320
  // 64-bit vector types.
 
1321
  def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, itinD16,
 
1322
                      OpcodeStr, !strconcat(Dt, "16"),
 
1323
                      v4i16, v4i16, IntOp, Commutable>;
 
1324
  def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, itinD32,
 
1325
                      OpcodeStr, !strconcat(Dt, "32"),
 
1326
                      v2i32, v2i32, IntOp, Commutable>;
 
1327
 
 
1328
  // 128-bit vector types.
 
1329
  def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, itinQ16,
 
1330
                      OpcodeStr, !strconcat(Dt, "16"),
 
1331
                      v8i16, v8i16, IntOp, Commutable>;
 
1332
  def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, itinQ32,
 
1333
                      OpcodeStr, !strconcat(Dt, "32"),
 
1334
                      v4i32, v4i32, IntOp, Commutable>;
 
1335
}
 
1336
 
 
1337
multiclass N3VIntSL_HS<bits<4> op11_8, 
 
1338
                       InstrItinClass itinD16, InstrItinClass itinD32,
 
1339
                       InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1340
                       string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1341
  def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16,
 
1342
                          OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>;
 
1343
  def v2i32 : N3VDIntSL<0b10, op11_8, itinD32,
 
1344
                        OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>;
 
1345
  def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16,
 
1346
                          OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>;
 
1347
  def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32,
 
1348
                        OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>;
 
1349
}
 
1350
 
 
1351
// ....then also with element size of 8 bits:
 
1352
multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1353
                      InstrItinClass itinD16, InstrItinClass itinD32,
 
1354
                      InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1355
                      string OpcodeStr, string Dt,
 
1356
                      Intrinsic IntOp, bit Commutable = 0>
 
1357
  : N3VInt_HS<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
 
1358
              OpcodeStr, Dt, IntOp, Commutable> {
 
1359
  def v8i8  : N3VDInt<op24, op23, 0b00, op11_8, op4, itinD16,
 
1360
                      OpcodeStr, !strconcat(Dt, "8"),
 
1361
                      v8i8, v8i8, IntOp, Commutable>;
 
1362
  def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, itinQ16,
 
1363
                      OpcodeStr, !strconcat(Dt, "8"),
 
1364
                      v16i8, v16i8, IntOp, Commutable>;
 
1365
}
 
1366
 
 
1367
// ....then also with element size of 64 bits:
 
1368
multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1369
                       InstrItinClass itinD16, InstrItinClass itinD32,
 
1370
                       InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1371
                       string OpcodeStr, string Dt,
 
1372
                       Intrinsic IntOp, bit Commutable = 0>
 
1373
  : N3VInt_QHS<op24, op23, op11_8, op4, itinD16, itinD32, itinQ16, itinQ32,
 
1374
               OpcodeStr, Dt, IntOp, Commutable> {
 
1375
  def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, itinD32,
 
1376
                      OpcodeStr, !strconcat(Dt, "64"),
 
1377
                      v1i64, v1i64, IntOp, Commutable>;
 
1378
  def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, itinQ32,
 
1379
                      OpcodeStr, !strconcat(Dt, "64"),
 
1380
                      v2i64, v2i64, IntOp, Commutable>;
 
1381
}
 
1382
 
 
1383
 
 
1384
// Neon Narrowing 3-register vector intrinsics,
 
1385
//   source operand element sizes of 16, 32 and 64 bits:
 
1386
multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1387
                       string OpcodeStr, string Dt,
 
1388
                       Intrinsic IntOp, bit Commutable = 0> {
 
1389
  def v8i8  : N3VNInt<op24, op23, 0b00, op11_8, op4,
 
1390
                      OpcodeStr, !strconcat(Dt, "16"),
 
1391
                      v8i8, v8i16, IntOp, Commutable>;
 
1392
  def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4,
 
1393
                      OpcodeStr, !strconcat(Dt, "32"),
 
1394
                      v4i16, v4i32, IntOp, Commutable>;
 
1395
  def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4,
 
1396
                      OpcodeStr, !strconcat(Dt, "64"),
 
1397
                      v2i32, v2i64, IntOp, Commutable>;
 
1398
}
 
1399
 
 
1400
 
 
1401
// Neon Long 3-register vector intrinsics.
 
1402
 
 
1403
// First with only element sizes of 16 and 32 bits:
 
1404
multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1405
                      InstrItinClass itin, string OpcodeStr, string Dt,
 
1406
                      Intrinsic IntOp, bit Commutable = 0> {
 
1407
  def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin, 
 
1408
                      OpcodeStr, !strconcat(Dt, "16"),
 
1409
                      v4i32, v4i16, IntOp, Commutable>;
 
1410
  def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin,
 
1411
                      OpcodeStr, !strconcat(Dt, "32"),
 
1412
                      v2i64, v2i32, IntOp, Commutable>;
 
1413
}
 
1414
 
 
1415
multiclass N3VLIntSL_HS<bit op24, bits<4> op11_8,
 
1416
                        InstrItinClass itin, string OpcodeStr, string Dt,
 
1417
                        Intrinsic IntOp> {
 
1418
  def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin, 
 
1419
                          OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
 
1420
  def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin,
 
1421
                        OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
 
1422
}
 
1423
 
 
1424
// ....then also with element size of 8 bits:
 
1425
multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1426
                       InstrItinClass itin, string OpcodeStr, string Dt,
 
1427
                       Intrinsic IntOp, bit Commutable = 0>
 
1428
  : N3VLInt_HS<op24, op23, op11_8, op4, itin, OpcodeStr, Dt,
 
1429
               IntOp, Commutable> {
 
1430
  def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin, 
 
1431
                      OpcodeStr, !strconcat(Dt, "8"),
 
1432
                      v8i16, v8i8, IntOp, Commutable>;
 
1433
}
 
1434
 
 
1435
 
 
1436
// Neon Wide 3-register vector intrinsics,
 
1437
//   source operand element sizes of 8, 16 and 32 bits:
 
1438
multiclass N3VWInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1439
                       string OpcodeStr, string Dt,
 
1440
                       Intrinsic IntOp, bit Commutable = 0> {
 
1441
  def v8i16 : N3VWInt<op24, op23, 0b00, op11_8, op4,
 
1442
                      OpcodeStr, !strconcat(Dt, "8"),
 
1443
                      v8i16, v8i8, IntOp, Commutable>;
 
1444
  def v4i32 : N3VWInt<op24, op23, 0b01, op11_8, op4,
 
1445
                      OpcodeStr, !strconcat(Dt, "16"),
 
1446
                      v4i32, v4i16, IntOp, Commutable>;
 
1447
  def v2i64 : N3VWInt<op24, op23, 0b10, op11_8, op4,
 
1448
                      OpcodeStr, !strconcat(Dt, "32"),
 
1449
                      v2i64, v2i32, IntOp, Commutable>;
 
1450
}
 
1451
 
 
1452
 
 
1453
// Neon Multiply-Op vector operations,
 
1454
//   element sizes of 8, 16 and 32 bits:
 
1455
multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1456
                        InstrItinClass itinD16, InstrItinClass itinD32,
 
1457
                        InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1458
                        string OpcodeStr, string Dt, SDNode OpNode> {
 
1459
  // 64-bit vector types.
 
1460
  def v8i8  : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16,
 
1461
                        OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>;
 
1462
  def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16,
 
1463
                        OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>;
 
1464
  def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32,
 
1465
                        OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>;
 
1466
 
 
1467
  // 128-bit vector types.
 
1468
  def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16,
 
1469
                        OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>;
 
1470
  def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16,
 
1471
                        OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>;
 
1472
  def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32,
 
1473
                        OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>;
 
1474
}
 
1475
 
 
1476
multiclass N3VMulOpSL_HS<bits<4> op11_8, 
 
1477
                         InstrItinClass itinD16, InstrItinClass itinD32,
 
1478
                         InstrItinClass itinQ16, InstrItinClass itinQ32,
 
1479
                         string OpcodeStr, string Dt, SDNode ShOp> {
 
1480
  def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16,
 
1481
                            OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>;
 
1482
  def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,
 
1483
                          OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>;
 
1484
  def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16,
 
1485
                            OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16,
 
1486
                            mul, ShOp>;
 
1487
  def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32,
 
1488
                          OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32,
 
1489
                          mul, ShOp>;
 
1490
}
 
1491
 
 
1492
// Neon 3-argument intrinsics,
 
1493
//   element sizes of 8, 16 and 32 bits:
 
1494
multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1495
                       string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1496
  // 64-bit vector types.
 
1497
  def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, IIC_VMACi16D,
 
1498
                       OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
 
1499
  def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, IIC_VMACi16D,
 
1500
                       OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
 
1501
  def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, IIC_VMACi32D,
 
1502
                       OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
 
1503
 
 
1504
  // 128-bit vector types.
 
1505
  def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, IIC_VMACi16Q,
 
1506
                       OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
 
1507
  def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, IIC_VMACi16Q,
 
1508
                       OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
 
1509
  def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, IIC_VMACi32Q,
 
1510
                       OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
 
1511
}
 
1512
 
 
1513
 
 
1514
// Neon Long 3-argument intrinsics.
 
1515
 
 
1516
// First with only element sizes of 16 and 32 bits:
 
1517
multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1518
                       string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1519
  def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, IIC_VMACi16D,
 
1520
                       OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>;
 
1521
  def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, IIC_VMACi16D,
 
1522
                       OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
 
1523
}
 
1524
 
 
1525
multiclass N3VLInt3SL_HS<bit op24, bits<4> op11_8,
 
1526
                         string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1527
  def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D,
 
1528
                           OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>;
 
1529
  def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D,
 
1530
                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>;
 
1531
}
 
1532
 
 
1533
// ....then also with element size of 8 bits:
 
1534
multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1535
                        string OpcodeStr, string Dt, Intrinsic IntOp>
 
1536
  : N3VLInt3_HS<op24, op23, op11_8, op4, OpcodeStr, Dt, IntOp> {
 
1537
  def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, IIC_VMACi16D,
 
1538
                       OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>;
 
1539
}
 
1540
 
 
1541
 
 
1542
// Neon 2-register vector intrinsics,
 
1543
//   element sizes of 8, 16 and 32 bits:
 
1544
multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
 
1545
                      bits<5> op11_7, bit op4,
 
1546
                      InstrItinClass itinD, InstrItinClass itinQ,
 
1547
                      string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1548
  // 64-bit vector types.
 
1549
  def v8i8  : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1550
                      itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
 
1551
  def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1552
                      itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>;
 
1553
  def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1554
                      itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>;
 
1555
 
 
1556
  // 128-bit vector types.
 
1557
  def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1558
                      itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>;
 
1559
  def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1560
                      itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>;
 
1561
  def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1562
                      itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>;
 
1563
}
 
1564
 
 
1565
 
 
1566
// Neon Pairwise long 2-register intrinsics,
 
1567
//   element sizes of 8, 16 and 32 bits:
 
1568
multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
 
1569
                        bits<5> op11_7, bit op4,
 
1570
                        string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1571
  // 64-bit vector types.
 
1572
  def v8i8  : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1573
                        OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
 
1574
  def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1575
                        OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
 
1576
  def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1577
                        OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
 
1578
 
 
1579
  // 128-bit vector types.
 
1580
  def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1581
                        OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
 
1582
  def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1583
                        OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
 
1584
  def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1585
                        OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
 
1586
}
 
1587
 
 
1588
 
 
1589
// Neon Pairwise long 2-register accumulate intrinsics,
 
1590
//   element sizes of 8, 16 and 32 bits:
 
1591
multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16,
 
1592
                         bits<5> op11_7, bit op4,
 
1593
                         string OpcodeStr, string Dt, Intrinsic IntOp> {
 
1594
  // 64-bit vector types.
 
1595
  def v8i8  : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1596
                         OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>;
 
1597
  def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1598
                         OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>;
 
1599
  def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1600
                         OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>;
 
1601
 
 
1602
  // 128-bit vector types.
 
1603
  def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4,
 
1604
                         OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>;
 
1605
  def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4,
 
1606
                         OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>;
 
1607
  def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4,
 
1608
                         OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>;
 
1609
}
 
1610
 
 
1611
 
 
1612
// Neon 2-register vector shift by immediate,
 
1613
//   element sizes of 8, 16, 32 and 64 bits:
 
1614
multiclass N2VSh_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1615
                      InstrItinClass itin, string OpcodeStr, string Dt,
 
1616
                      SDNode OpNode> {
 
1617
  // 64-bit vector types.
 
1618
  def v8i8  : N2VDSh<op24, op23, op11_8, 0, op4, itin,
 
1619
                     OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> {
 
1620
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1621
  }
 
1622
  def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, itin,
 
1623
                     OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> {
 
1624
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1625
  }
 
1626
  def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, itin,
 
1627
                     OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> {
 
1628
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1629
  }
 
1630
  def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, itin,
 
1631
                     OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>;
 
1632
                             // imm6 = xxxxxx
 
1633
 
 
1634
  // 128-bit vector types.
 
1635
  def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
 
1636
                     OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> {
 
1637
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1638
  }
 
1639
  def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
 
1640
                     OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> {
 
1641
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1642
  }
 
1643
  def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, itin,
 
1644
                     OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> {
 
1645
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1646
  }
 
1647
  def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, itin,
 
1648
                     OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>;
 
1649
                             // imm6 = xxxxxx
 
1650
}
 
1651
 
 
1652
 
 
1653
// Neon Shift-Accumulate vector operations,
 
1654
//   element sizes of 8, 16, 32 and 64 bits:
 
1655
multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1656
                         string OpcodeStr, string Dt, SDNode ShOp> {
 
1657
  // 64-bit vector types.
 
1658
  def v8i8  : N2VDShAdd<op24, op23, op11_8, 0, op4,
 
1659
                        OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> {
 
1660
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1661
  }
 
1662
  def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4,
 
1663
                        OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> {
 
1664
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1665
  }
 
1666
  def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4,
 
1667
                        OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> {
 
1668
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1669
  }
 
1670
  def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4,
 
1671
                        OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>;
 
1672
                             // imm6 = xxxxxx
 
1673
 
 
1674
  // 128-bit vector types.
 
1675
  def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4,
 
1676
                        OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> {
 
1677
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1678
  }
 
1679
  def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4,
 
1680
                        OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> {
 
1681
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1682
  }
 
1683
  def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4,
 
1684
                        OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> {
 
1685
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1686
  }
 
1687
  def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4,
 
1688
                        OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>;
 
1689
                             // imm6 = xxxxxx
 
1690
}
 
1691
 
 
1692
 
 
1693
// Neon Shift-Insert vector operations,
 
1694
//   element sizes of 8, 16, 32 and 64 bits:
 
1695
multiclass N2VShIns_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4,
 
1696
                         string OpcodeStr, SDNode ShOp> {
 
1697
  // 64-bit vector types.
 
1698
  def v8i8  : N2VDShIns<op24, op23, op11_8, 0, op4,
 
1699
                        OpcodeStr, "8", v8i8, ShOp> {
 
1700
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1701
  }
 
1702
  def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4,
 
1703
                        OpcodeStr, "16", v4i16, ShOp> {
 
1704
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1705
  }
 
1706
  def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4,
 
1707
                        OpcodeStr, "32", v2i32, ShOp> {
 
1708
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1709
  }
 
1710
  def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4,
 
1711
                        OpcodeStr, "64", v1i64, ShOp>;
 
1712
                             // imm6 = xxxxxx
 
1713
 
 
1714
  // 128-bit vector types.
 
1715
  def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4,
 
1716
                        OpcodeStr, "8", v16i8, ShOp> {
 
1717
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1718
  }
 
1719
  def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4,
 
1720
                        OpcodeStr, "16", v8i16, ShOp> {
 
1721
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1722
  }
 
1723
  def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4,
 
1724
                        OpcodeStr, "32", v4i32, ShOp> {
 
1725
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1726
  }
 
1727
  def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4,
 
1728
                        OpcodeStr, "64", v2i64, ShOp>;
 
1729
                             // imm6 = xxxxxx
 
1730
}
 
1731
 
 
1732
// Neon Shift Long operations,
 
1733
//   element sizes of 8, 16, 32 bits:
 
1734
multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
 
1735
                      bit op4, string OpcodeStr, string Dt, SDNode OpNode> {
 
1736
  def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
 
1737
                 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode> {
 
1738
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1739
  }
 
1740
  def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
 
1741
                  OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode> {
 
1742
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1743
  }
 
1744
  def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4,
 
1745
                  OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode> {
 
1746
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1747
  }
 
1748
}
 
1749
 
 
1750
// Neon Shift Narrow operations,
 
1751
//   element sizes of 16, 32, 64 bits:
 
1752
multiclass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6,
 
1753
                      bit op4, InstrItinClass itin, string OpcodeStr, string Dt,
 
1754
                      SDNode OpNode> {
 
1755
  def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
 
1756
                    OpcodeStr, !strconcat(Dt, "16"), v8i8, v8i16, OpNode> {
 
1757
    let Inst{21-19} = 0b001; // imm6 = 001xxx
 
1758
  }
 
1759
  def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
 
1760
                     OpcodeStr, !strconcat(Dt, "32"), v4i16, v4i32, OpNode> {
 
1761
    let Inst{21-20} = 0b01;  // imm6 = 01xxxx
 
1762
  }
 
1763
  def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin,
 
1764
                     OpcodeStr, !strconcat(Dt, "64"), v2i32, v2i64, OpNode> {
 
1765
    let Inst{21} = 0b1;      // imm6 = 1xxxxx
 
1766
  }
 
1767
}
 
1768
 
 
1769
//===----------------------------------------------------------------------===//
 
1770
// Instruction Definitions.
 
1771
//===----------------------------------------------------------------------===//
 
1772
 
 
1773
// Vector Add Operations.
 
1774
 
 
1775
//   VADD     : Vector Add (integer and floating-point)
 
1776
defm VADD     : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i",
 
1777
                         add, 1>;
 
1778
def  VADDfd   : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32",
 
1779
                     v2f32, v2f32, fadd, 1>;
 
1780
def  VADDfq   : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32",
 
1781
                     v4f32, v4f32, fadd, 1>;
 
1782
//   VADDL    : Vector Add Long (Q = D + D)
 
1783
defm VADDLs   : N3VLInt_QHS<0,1,0b0000,0, IIC_VSHLiD, "vaddl", "s",
 
1784
                            int_arm_neon_vaddls, 1>;
 
1785
defm VADDLu   : N3VLInt_QHS<1,1,0b0000,0, IIC_VSHLiD, "vaddl", "u",
 
1786
                            int_arm_neon_vaddlu, 1>;
 
1787
//   VADDW    : Vector Add Wide (Q = Q + D)
 
1788
defm VADDWs   : N3VWInt_QHS<0,1,0b0001,0, "vaddw", "s", int_arm_neon_vaddws, 0>;
 
1789
defm VADDWu   : N3VWInt_QHS<1,1,0b0001,0, "vaddw", "u", int_arm_neon_vaddwu, 0>;
 
1790
//   VHADD    : Vector Halving Add
 
1791
defm VHADDs   : N3VInt_QHS<0,0,0b0000,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1792
                           IIC_VBINi4Q, "vhadd", "s", int_arm_neon_vhadds, 1>;
 
1793
defm VHADDu   : N3VInt_QHS<1,0,0b0000,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1794
                           IIC_VBINi4Q, "vhadd", "u", int_arm_neon_vhaddu, 1>;
 
1795
//   VRHADD   : Vector Rounding Halving Add
 
1796
defm VRHADDs  : N3VInt_QHS<0,0,0b0001,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1797
                           IIC_VBINi4Q, "vrhadd", "s", int_arm_neon_vrhadds, 1>;
 
1798
defm VRHADDu  : N3VInt_QHS<1,0,0b0001,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1799
                           IIC_VBINi4Q, "vrhadd", "u", int_arm_neon_vrhaddu, 1>;
 
1800
//   VQADD    : Vector Saturating Add
 
1801
defm VQADDs   : N3VInt_QHSD<0,0,0b0000,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1802
                            IIC_VBINi4Q, "vqadd", "s", int_arm_neon_vqadds, 1>;
 
1803
defm VQADDu   : N3VInt_QHSD<1,0,0b0000,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
1804
                            IIC_VBINi4Q, "vqadd", "u", int_arm_neon_vqaddu, 1>;
 
1805
//   VADDHN   : Vector Add and Narrow Returning High Half (D = Q + Q)
 
1806
defm VADDHN   : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i",
 
1807
                            int_arm_neon_vaddhn, 1>;
 
1808
//   VRADDHN  : Vector Rounding Add and Narrow Returning High Half (D = Q + Q)
 
1809
defm VRADDHN  : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i",
 
1810
                            int_arm_neon_vraddhn, 1>;
 
1811
 
 
1812
// Vector Multiply Operations.
 
1813
 
 
1814
//   VMUL     : Vector Multiply (integer, polynomial and floating-point)
 
1815
defm VMUL     : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D,
 
1816
                        IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>;
 
1817
def  VMULpd   : N3VDInt<1, 0, 0b00, 0b1001, 1, IIC_VMULi16D, "vmul", "p8",
 
1818
                        v8i8, v8i8, int_arm_neon_vmulp, 1>;
 
1819
def  VMULpq   : N3VQInt<1, 0, 0b00, 0b1001, 1, IIC_VMULi16Q, "vmul", "p8",
 
1820
                        v16i8, v16i8, int_arm_neon_vmulp, 1>;
 
1821
def  VMULfd   : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VBIND, "vmul", "f32",
 
1822
                     v2f32, v2f32, fmul, 1>;
 
1823
def  VMULfq   : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VBINQ, "vmul", "f32",
 
1824
                     v4f32, v4f32, fmul, 1>;
 
1825
defm VMULsl   : N3VSL_HS<0b1000, "vmul", "i", mul>;
 
1826
def  VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>;
 
1827
def  VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32,
 
1828
                       v2f32, fmul>;
 
1829
 
 
1830
def : Pat<(v8i16 (mul (v8i16 QPR:$src1),
 
1831
                      (v8i16 (NEONvduplane (v8i16 QPR:$src2), imm:$lane)))),
 
1832
          (v8i16 (VMULslv8i16 (v8i16 QPR:$src1),
 
1833
                              (v4i16 (EXTRACT_SUBREG QPR:$src2,
 
1834
                                      (DSubReg_i16_reg imm:$lane))),
 
1835
                              (SubReg_i16_lane imm:$lane)))>;
 
1836
def : Pat<(v4i32 (mul (v4i32 QPR:$src1),
 
1837
                      (v4i32 (NEONvduplane (v4i32 QPR:$src2), imm:$lane)))),
 
1838
          (v4i32 (VMULslv4i32 (v4i32 QPR:$src1),
 
1839
                              (v2i32 (EXTRACT_SUBREG QPR:$src2,
 
1840
                                      (DSubReg_i32_reg imm:$lane))),
 
1841
                              (SubReg_i32_lane imm:$lane)))>;
 
1842
def : Pat<(v4f32 (fmul (v4f32 QPR:$src1),
 
1843
                       (v4f32 (NEONvduplane (v4f32 QPR:$src2), imm:$lane)))),
 
1844
          (v4f32 (VMULslfq (v4f32 QPR:$src1),
 
1845
                           (v2f32 (EXTRACT_SUBREG QPR:$src2,
 
1846
                                   (DSubReg_i32_reg imm:$lane))),
 
1847
                           (SubReg_i32_lane imm:$lane)))>;
 
1848
 
 
1849
//   VQDMULH  : Vector Saturating Doubling Multiply Returning High Half
 
1850
defm VQDMULH  : N3VInt_HS<0, 0, 0b1011, 0, IIC_VMULi16D, IIC_VMULi32D,
 
1851
                          IIC_VMULi16Q, IIC_VMULi32Q, 
 
1852
                          "vqdmulh", "s", int_arm_neon_vqdmulh, 1>;
 
1853
defm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D,
 
1854
                            IIC_VMULi16Q, IIC_VMULi32Q,
 
1855
                            "vqdmulh", "s",  int_arm_neon_vqdmulh>;
 
1856
def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1),
 
1857
                                       (v8i16 (NEONvduplane (v8i16 QPR:$src2),
 
1858
                                                            imm:$lane)))),
 
1859
          (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1),
 
1860
                                 (v4i16 (EXTRACT_SUBREG QPR:$src2,
 
1861
                                         (DSubReg_i16_reg imm:$lane))),
 
1862
                                 (SubReg_i16_lane imm:$lane)))>;
 
1863
def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1),
 
1864
                                       (v4i32 (NEONvduplane (v4i32 QPR:$src2),
 
1865
                                                            imm:$lane)))),
 
1866
          (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1),
 
1867
                                 (v2i32 (EXTRACT_SUBREG QPR:$src2,
 
1868
                                         (DSubReg_i32_reg imm:$lane))),
 
1869
                                 (SubReg_i32_lane imm:$lane)))>;
 
1870
 
 
1871
//   VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half
 
1872
defm VQRDMULH   : N3VInt_HS<1, 0, 0b1011, 0, IIC_VMULi16D, IIC_VMULi32D,
 
1873
                            IIC_VMULi16Q, IIC_VMULi32Q,
 
1874
                            "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>;
 
1875
defm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D,
 
1876
                              IIC_VMULi16Q, IIC_VMULi32Q,
 
1877
                              "vqrdmulh", "s",  int_arm_neon_vqrdmulh>;
 
1878
def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1),
 
1879
                                        (v8i16 (NEONvduplane (v8i16 QPR:$src2),
 
1880
                                                             imm:$lane)))),
 
1881
          (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1),
 
1882
                                  (v4i16 (EXTRACT_SUBREG QPR:$src2,
 
1883
                                          (DSubReg_i16_reg imm:$lane))),
 
1884
                                  (SubReg_i16_lane imm:$lane)))>;
 
1885
def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1),
 
1886
                                        (v4i32 (NEONvduplane (v4i32 QPR:$src2),
 
1887
                                                             imm:$lane)))),
 
1888
          (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1),
 
1889
                                  (v2i32 (EXTRACT_SUBREG QPR:$src2,
 
1890
                                          (DSubReg_i32_reg imm:$lane))),
 
1891
                                  (SubReg_i32_lane imm:$lane)))>;
 
1892
 
 
1893
//   VMULL    : Vector Multiply Long (integer and polynomial) (Q = D * D)
 
1894
defm VMULLs   : N3VLInt_QHS<0,1,0b1100,0, IIC_VMULi16D, "vmull", "s",
 
1895
                            int_arm_neon_vmulls, 1>;
 
1896
defm VMULLu   : N3VLInt_QHS<1,1,0b1100,0, IIC_VMULi16D, "vmull", "u",
 
1897
                            int_arm_neon_vmullu, 1>;
 
1898
def  VMULLp   : N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8",
 
1899
                        v8i16, v8i8, int_arm_neon_vmullp, 1>;
 
1900
defm VMULLsls : N3VLIntSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s",
 
1901
                             int_arm_neon_vmulls>;
 
1902
defm VMULLslu : N3VLIntSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u",
 
1903
                             int_arm_neon_vmullu>;
 
1904
 
 
1905
//   VQDMULL  : Vector Saturating Doubling Multiply Long (Q = D * D)
 
1906
defm VQDMULL  : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, "vqdmull", "s",
 
1907
                           int_arm_neon_vqdmull, 1>;
 
1908
defm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D, "vqdmull", "s",
 
1909
                             int_arm_neon_vqdmull>;
 
1910
 
 
1911
// Vector Multiply-Accumulate and Multiply-Subtract Operations.
 
1912
 
 
1913
//   VMLA     : Vector Multiply Accumulate (integer and floating-point)
 
1914
defm VMLA     : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
 
1915
                             IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
 
1916
def  VMLAfd   : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32",
 
1917
                          v2f32, fmul, fadd>;
 
1918
def  VMLAfq   : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32",
 
1919
                          v4f32, fmul, fadd>;
 
1920
defm VMLAsl   : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D,
 
1921
                              IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>;
 
1922
def  VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32",
 
1923
                            v2f32, fmul, fadd>;
 
1924
def  VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32",
 
1925
                            v4f32, v2f32, fmul, fadd>;
 
1926
 
 
1927
def : Pat<(v8i16 (add (v8i16 QPR:$src1),
 
1928
                  (mul (v8i16 QPR:$src2),
 
1929
                       (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
 
1930
          (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
 
1931
                              (v4i16 (EXTRACT_SUBREG QPR:$src3,
 
1932
                                      (DSubReg_i16_reg imm:$lane))),
 
1933
                              (SubReg_i16_lane imm:$lane)))>;
 
1934
 
 
1935
def : Pat<(v4i32 (add (v4i32 QPR:$src1),
 
1936
                  (mul (v4i32 QPR:$src2),
 
1937
                       (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
 
1938
          (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
 
1939
                              (v2i32 (EXTRACT_SUBREG QPR:$src3,
 
1940
                                      (DSubReg_i32_reg imm:$lane))),
 
1941
                              (SubReg_i32_lane imm:$lane)))>;
 
1942
 
 
1943
def : Pat<(v4f32 (fadd (v4f32 QPR:$src1),
 
1944
                  (fmul (v4f32 QPR:$src2),
 
1945
                        (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
 
1946
          (v4f32 (VMLAslfq (v4f32 QPR:$src1),
 
1947
                           (v4f32 QPR:$src2),
 
1948
                           (v2f32 (EXTRACT_SUBREG QPR:$src3,
 
1949
                                   (DSubReg_i32_reg imm:$lane))),
 
1950
                           (SubReg_i32_lane imm:$lane)))>;
 
1951
 
 
1952
//   VMLAL    : Vector Multiply Accumulate Long (Q += D * D)
 
1953
defm VMLALs   : N3VLInt3_QHS<0,1,0b1000,0, "vmlal", "s", int_arm_neon_vmlals>;
 
1954
defm VMLALu   : N3VLInt3_QHS<1,1,0b1000,0, "vmlal", "u", int_arm_neon_vmlalu>;
 
1955
 
 
1956
defm VMLALsls : N3VLInt3SL_HS<0, 0b0010, "vmlal", "s", int_arm_neon_vmlals>;
 
1957
defm VMLALslu : N3VLInt3SL_HS<1, 0b0010, "vmlal", "u", int_arm_neon_vmlalu>;
 
1958
 
 
1959
//   VQDMLAL  : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D)
 
1960
defm VQDMLAL  : N3VLInt3_HS<0, 1, 0b1001, 0, "vqdmlal", "s",
 
1961
                            int_arm_neon_vqdmlal>;
 
1962
defm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", int_arm_neon_vqdmlal>;
 
1963
 
 
1964
//   VMLS     : Vector Multiply Subtract (integer and floating-point)
 
1965
defm VMLS     : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
 
1966
                             IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
 
1967
def  VMLSfd   : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32",
 
1968
                          v2f32, fmul, fsub>;
 
1969
def  VMLSfq   : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32",
 
1970
                          v4f32, fmul, fsub>;
 
1971
defm VMLSsl   : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D,
 
1972
                              IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>;
 
1973
def  VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32",
 
1974
                            v2f32, fmul, fsub>;
 
1975
def  VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32",
 
1976
                            v4f32, v2f32, fmul, fsub>;
 
1977
 
 
1978
def : Pat<(v8i16 (sub (v8i16 QPR:$src1),
 
1979
                  (mul (v8i16 QPR:$src2),
 
1980
                       (v8i16 (NEONvduplane (v8i16 QPR:$src3), imm:$lane))))),
 
1981
          (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2),
 
1982
                              (v4i16 (EXTRACT_SUBREG QPR:$src3,
 
1983
                                      (DSubReg_i16_reg imm:$lane))),
 
1984
                              (SubReg_i16_lane imm:$lane)))>;
 
1985
 
 
1986
def : Pat<(v4i32 (sub (v4i32 QPR:$src1),
 
1987
                  (mul (v4i32 QPR:$src2),
 
1988
                     (v4i32 (NEONvduplane (v4i32 QPR:$src3), imm:$lane))))),
 
1989
          (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2),
 
1990
                              (v2i32 (EXTRACT_SUBREG QPR:$src3,
 
1991
                                      (DSubReg_i32_reg imm:$lane))),
 
1992
                              (SubReg_i32_lane imm:$lane)))>;
 
1993
 
 
1994
def : Pat<(v4f32 (fsub (v4f32 QPR:$src1),
 
1995
                  (fmul (v4f32 QPR:$src2),
 
1996
                        (v4f32 (NEONvduplane (v4f32 QPR:$src3), imm:$lane))))),
 
1997
          (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2),
 
1998
                           (v2f32 (EXTRACT_SUBREG QPR:$src3,
 
1999
                                   (DSubReg_i32_reg imm:$lane))),
 
2000
                           (SubReg_i32_lane imm:$lane)))>;
 
2001
 
 
2002
//   VMLSL    : Vector Multiply Subtract Long (Q -= D * D)
 
2003
defm VMLSLs   : N3VLInt3_QHS<0,1,0b1010,0, "vmlsl", "s", int_arm_neon_vmlsls>;
 
2004
defm VMLSLu   : N3VLInt3_QHS<1,1,0b1010,0, "vmlsl", "u", int_arm_neon_vmlslu>;
 
2005
 
 
2006
defm VMLSLsls : N3VLInt3SL_HS<0, 0b0110, "vmlsl", "s", int_arm_neon_vmlsls>;
 
2007
defm VMLSLslu : N3VLInt3SL_HS<1, 0b0110, "vmlsl", "u", int_arm_neon_vmlslu>;
 
2008
 
 
2009
//   VQDMLSL  : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D)
 
2010
defm VQDMLSL  : N3VLInt3_HS<0, 1, 0b1011, 0, "vqdmlsl", "s",
 
2011
                            int_arm_neon_vqdmlsl>;
 
2012
defm VQDMLSLsl: N3VLInt3SL_HS<0, 0b111, "vqdmlsl", "s", int_arm_neon_vqdmlsl>;
 
2013
 
 
2014
// Vector Subtract Operations.
 
2015
 
 
2016
//   VSUB     : Vector Subtract (integer and floating-point)
 
2017
defm VSUB     : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ,
 
2018
                         "vsub", "i", sub, 0>;
 
2019
def  VSUBfd   : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32",
 
2020
                     v2f32, v2f32, fsub, 0>;
 
2021
def  VSUBfq   : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32",
 
2022
                     v4f32, v4f32, fsub, 0>;
 
2023
//   VSUBL    : Vector Subtract Long (Q = D - D)
 
2024
defm VSUBLs   : N3VLInt_QHS<0,1,0b0010,0, IIC_VSHLiD, "vsubl", "s",
 
2025
                            int_arm_neon_vsubls, 1>;
 
2026
defm VSUBLu   : N3VLInt_QHS<1,1,0b0010,0, IIC_VSHLiD, "vsubl", "u",
 
2027
                            int_arm_neon_vsublu, 1>;
 
2028
//   VSUBW    : Vector Subtract Wide (Q = Q - D)
 
2029
defm VSUBWs   : N3VWInt_QHS<0,1,0b0011,0, "vsubw", "s", int_arm_neon_vsubws, 0>;
 
2030
defm VSUBWu   : N3VWInt_QHS<1,1,0b0011,0, "vsubw", "u", int_arm_neon_vsubwu, 0>;
 
2031
//   VHSUB    : Vector Halving Subtract
 
2032
defm VHSUBs   : N3VInt_QHS<0, 0, 0b0010, 0, IIC_VBINi4D, IIC_VBINi4D,
 
2033
                           IIC_VBINi4Q, IIC_VBINi4Q,
 
2034
                           "vhsub", "s", int_arm_neon_vhsubs, 0>;
 
2035
defm VHSUBu   : N3VInt_QHS<1, 0, 0b0010, 0, IIC_VBINi4D, IIC_VBINi4D,
 
2036
                           IIC_VBINi4Q, IIC_VBINi4Q,
 
2037
                           "vhsub", "u", int_arm_neon_vhsubu, 0>;
 
2038
//   VQSUB    : Vector Saturing Subtract
 
2039
defm VQSUBs   : N3VInt_QHSD<0, 0, 0b0010, 1, IIC_VBINi4D, IIC_VBINi4D,
 
2040
                            IIC_VBINi4Q, IIC_VBINi4Q,
 
2041
                            "vqsub", "s", int_arm_neon_vqsubs, 0>;
 
2042
defm VQSUBu   : N3VInt_QHSD<1, 0, 0b0010, 1, IIC_VBINi4D, IIC_VBINi4D,
 
2043
                            IIC_VBINi4Q, IIC_VBINi4Q,
 
2044
                            "vqsub", "u", int_arm_neon_vqsubu, 0>;
 
2045
//   VSUBHN   : Vector Subtract and Narrow Returning High Half (D = Q - Q)
 
2046
defm VSUBHN   : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i",
 
2047
                            int_arm_neon_vsubhn, 0>;
 
2048
//   VRSUBHN  : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q)
 
2049
defm VRSUBHN  : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i",
 
2050
                            int_arm_neon_vrsubhn, 0>;
 
2051
 
 
2052
// Vector Comparisons.
 
2053
 
 
2054
//   VCEQ     : Vector Compare Equal
 
2055
defm VCEQ     : N3V_QHS<1, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2056
                        IIC_VBINi4Q, "vceq", "i", NEONvceq, 1>;
 
2057
def  VCEQfd   : N3VD<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32,
 
2058
                     NEONvceq, 1>;
 
2059
def  VCEQfq   : N3VQ<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32,
 
2060
                     NEONvceq, 1>;
 
2061
// For disassembly only.
 
2062
defm VCEQz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i",
 
2063
                           "$dst, $src, #0">;
 
2064
 
 
2065
//   VCGE     : Vector Compare Greater Than or Equal
 
2066
defm VCGEs    : N3V_QHS<0, 0, 0b0011, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2067
                        IIC_VBINi4Q, "vcge", "s", NEONvcge, 0>;
 
2068
defm VCGEu    : N3V_QHS<1, 0, 0b0011, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 
 
2069
                        IIC_VBINi4Q, "vcge", "u", NEONvcgeu, 0>;
 
2070
def  VCGEfd   : N3VD<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32",
 
2071
                     v2i32, v2f32, NEONvcge, 0>;
 
2072
def  VCGEfq   : N3VQ<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32,
 
2073
                     NEONvcge, 0>;
 
2074
// For disassembly only.
 
2075
defm VCGEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s",
 
2076
                            "$dst, $src, #0">;
 
2077
// For disassembly only.
 
2078
defm VCLEz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s",
 
2079
                            "$dst, $src, #0">;
 
2080
 
 
2081
//   VCGT     : Vector Compare Greater Than
 
2082
defm VCGTs    : N3V_QHS<0, 0, 0b0011, 0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 
 
2083
                        IIC_VBINi4Q, "vcgt", "s", NEONvcgt, 0>;
 
2084
defm VCGTu    : N3V_QHS<1, 0, 0b0011, 0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 
 
2085
                        IIC_VBINi4Q, "vcgt", "u", NEONvcgtu, 0>;
 
2086
def  VCGTfd   : N3VD<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32,
 
2087
                     NEONvcgt, 0>;
 
2088
def  VCGTfq   : N3VQ<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32,
 
2089
                     NEONvcgt, 0>;
 
2090
// For disassembly only.
 
2091
defm VCGTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s",
 
2092
                            "$dst, $src, #0">;
 
2093
// For disassembly only.
 
2094
defm VCLTz    : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s",
 
2095
                            "$dst, $src, #0">;
 
2096
 
 
2097
//   VACGE    : Vector Absolute Compare Greater Than or Equal (aka VCAGE)
 
2098
def  VACGEd   : N3VDInt<1, 0, 0b00, 0b1110, 1, IIC_VBIND, "vacge", "f32",
 
2099
                        v2i32, v2f32, int_arm_neon_vacged, 0>;
 
2100
def  VACGEq   : N3VQInt<1, 0, 0b00, 0b1110, 1, IIC_VBINQ, "vacge", "f32",
 
2101
                        v4i32, v4f32, int_arm_neon_vacgeq, 0>;
 
2102
//   VACGT    : Vector Absolute Compare Greater Than (aka VCAGT)
 
2103
def  VACGTd   : N3VDInt<1, 0, 0b10, 0b1110, 1, IIC_VBIND, "vacgt", "f32",
 
2104
                        v2i32, v2f32, int_arm_neon_vacgtd, 0>;
 
2105
def  VACGTq   : N3VQInt<1, 0, 0b10, 0b1110, 1, IIC_VBINQ, "vacgt", "f32",
 
2106
                        v4i32, v4f32, int_arm_neon_vacgtq, 0>;
 
2107
//   VTST     : Vector Test Bits
 
2108
defm VTST     : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 
 
2109
                        IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;
 
2110
 
 
2111
// Vector Bitwise Operations.
 
2112
 
 
2113
//   VAND     : Vector Bitwise AND
 
2114
def  VANDd    : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand",
 
2115
                      v2i32, v2i32, and, 1>;
 
2116
def  VANDq    : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand",
 
2117
                      v4i32, v4i32, and, 1>;
 
2118
 
 
2119
//   VEOR     : Vector Bitwise Exclusive OR
 
2120
def  VEORd    : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor",
 
2121
                      v2i32, v2i32, xor, 1>;
 
2122
def  VEORq    : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor",
 
2123
                      v4i32, v4i32, xor, 1>;
 
2124
 
 
2125
//   VORR     : Vector Bitwise OR
 
2126
def  VORRd    : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr",
 
2127
                      v2i32, v2i32, or, 1>;
 
2128
def  VORRq    : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr",
 
2129
                      v4i32, v4i32, or, 1>;
 
2130
 
 
2131
//   VBIC     : Vector Bitwise Bit Clear (AND NOT)
 
2132
def  VBICd    : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst),
 
2133
                    (ins DPR:$src1, DPR:$src2), IIC_VBINiD,
 
2134
                    "vbic", "$dst, $src1, $src2", "",
 
2135
                    [(set DPR:$dst, (v2i32 (and DPR:$src1,
 
2136
                                                (vnot_conv DPR:$src2))))]>;
 
2137
def  VBICq    : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst),
 
2138
                    (ins QPR:$src1, QPR:$src2), IIC_VBINiQ,
 
2139
                    "vbic", "$dst, $src1, $src2", "",
 
2140
                    [(set QPR:$dst, (v4i32 (and QPR:$src1,
 
2141
                                                (vnot_conv QPR:$src2))))]>;
 
2142
 
 
2143
//   VORN     : Vector Bitwise OR NOT
 
2144
def  VORNd    : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$dst),
 
2145
                    (ins DPR:$src1, DPR:$src2), IIC_VBINiD,
 
2146
                    "vorn", "$dst, $src1, $src2", "",
 
2147
                    [(set DPR:$dst, (v2i32 (or DPR:$src1,
 
2148
                                               (vnot_conv DPR:$src2))))]>;
 
2149
def  VORNq    : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$dst),
 
2150
                    (ins QPR:$src1, QPR:$src2), IIC_VBINiQ,
 
2151
                    "vorn", "$dst, $src1, $src2", "",
 
2152
                    [(set QPR:$dst, (v4i32 (or QPR:$src1,
 
2153
                                               (vnot_conv QPR:$src2))))]>;
 
2154
 
 
2155
//   VMVN     : Vector Bitwise NOT
 
2156
def  VMVNd    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0,
 
2157
                    (outs DPR:$dst), (ins DPR:$src), IIC_VSHLiD,
 
2158
                    "vmvn", "$dst, $src", "",
 
2159
                    [(set DPR:$dst, (v2i32 (vnot DPR:$src)))]>;
 
2160
def  VMVNq    : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0,
 
2161
                    (outs QPR:$dst), (ins QPR:$src), IIC_VSHLiD,
 
2162
                    "vmvn", "$dst, $src", "",
 
2163
                    [(set QPR:$dst, (v4i32 (vnot QPR:$src)))]>;
 
2164
def : Pat<(v2i32 (vnot_conv DPR:$src)), (VMVNd DPR:$src)>;
 
2165
def : Pat<(v4i32 (vnot_conv QPR:$src)), (VMVNq QPR:$src)>;
 
2166
 
 
2167
//   VBSL     : Vector Bitwise Select
 
2168
def  VBSLd    : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst),
 
2169
                    (ins DPR:$src1, DPR:$src2, DPR:$src3), IIC_VCNTiD,
 
2170
                    "vbsl", "$dst, $src2, $src3", "$src1 = $dst",
 
2171
                    [(set DPR:$dst,
 
2172
                      (v2i32 (or (and DPR:$src2, DPR:$src1),
 
2173
                                 (and DPR:$src3, (vnot_conv DPR:$src1)))))]>;
 
2174
def  VBSLq    : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst),
 
2175
                    (ins QPR:$src1, QPR:$src2, QPR:$src3), IIC_VCNTiQ,
 
2176
                    "vbsl", "$dst, $src2, $src3", "$src1 = $dst",
 
2177
                    [(set QPR:$dst,
 
2178
                      (v4i32 (or (and QPR:$src2, QPR:$src1),
 
2179
                                 (and QPR:$src3, (vnot_conv QPR:$src1)))))]>;
 
2180
 
 
2181
//   VBIF     : Vector Bitwise Insert if False
 
2182
//              like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
 
2183
def  VBIFd    : N3VX<1, 0, 0b11, 0b0001, 0, 1,
 
2184
                     (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
 
2185
                     IIC_VBINiD, "vbif", "$dst, $src2, $src3", "$src1 = $dst",
 
2186
                     [/* For disassembly only; pattern left blank */]>;
 
2187
def  VBIFq    : N3VX<1, 0, 0b11, 0b0001, 1, 1,
 
2188
                     (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
 
2189
                     IIC_VBINiQ, "vbif", "$dst, $src2, $src3", "$src1 = $dst",
 
2190
                     [/* For disassembly only; pattern left blank */]>;
 
2191
 
 
2192
//   VBIT     : Vector Bitwise Insert if True
 
2193
//              like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst",
 
2194
def  VBITd    : N3VX<1, 0, 0b10, 0b0001, 0, 1,
 
2195
                     (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
 
2196
                     IIC_VBINiD, "vbit", "$dst, $src2, $src3", "$src1 = $dst",
 
2197
                     [/* For disassembly only; pattern left blank */]>;
 
2198
def  VBITq    : N3VX<1, 0, 0b10, 0b0001, 1, 1,
 
2199
                     (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
 
2200
                     IIC_VBINiQ, "vbit", "$dst, $src2, $src3", "$src1 = $dst",
 
2201
                     [/* For disassembly only; pattern left blank */]>;
 
2202
 
 
2203
// VBIT/VBIF are not yet implemented.  The TwoAddress pass will not go looking
 
2204
// for equivalent operations with different register constraints; it just
 
2205
// inserts copies.
 
2206
 
 
2207
// Vector Absolute Differences.
 
2208
 
 
2209
//   VABD     : Vector Absolute Difference
 
2210
defm VABDs    : N3VInt_QHS<0, 0, 0b0111, 0, IIC_VBINi4D, IIC_VBINi4D,
 
2211
                           IIC_VBINi4Q, IIC_VBINi4Q,
 
2212
                           "vabd", "s", int_arm_neon_vabds, 0>;
 
2213
defm VABDu    : N3VInt_QHS<1, 0, 0b0111, 0, IIC_VBINi4D, IIC_VBINi4D,
 
2214
                           IIC_VBINi4Q, IIC_VBINi4Q,
 
2215
                           "vabd", "u", int_arm_neon_vabdu, 0>;
 
2216
def  VABDfd   : N3VDInt<1, 0, 0b10, 0b1101, 0, IIC_VBIND,
 
2217
                        "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 0>;
 
2218
def  VABDfq   : N3VQInt<1, 0, 0b10, 0b1101, 0, IIC_VBINQ,
 
2219
                        "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 0>;
 
2220
 
 
2221
//   VABDL    : Vector Absolute Difference Long (Q = | D - D |)
 
2222
defm VABDLs   : N3VLInt_QHS<0,1,0b0111,0, IIC_VBINi4Q,
 
2223
                            "vabdl", "s", int_arm_neon_vabdls, 0>;
 
2224
defm VABDLu   : N3VLInt_QHS<1,1,0b0111,0, IIC_VBINi4Q,
 
2225
                             "vabdl", "u", int_arm_neon_vabdlu, 0>;
 
2226
 
 
2227
//   VABA     : Vector Absolute Difference and Accumulate
 
2228
defm VABAs    : N3VInt3_QHS<0,0,0b0111,1, "vaba", "s", int_arm_neon_vabas>;
 
2229
defm VABAu    : N3VInt3_QHS<1,0,0b0111,1, "vaba", "u", int_arm_neon_vabau>;
 
2230
 
 
2231
//   VABAL    : Vector Absolute Difference and Accumulate Long (Q += | D - D |)
 
2232
defm VABALs   : N3VLInt3_QHS<0,1,0b0101,0, "vabal", "s", int_arm_neon_vabals>;
 
2233
defm VABALu   : N3VLInt3_QHS<1,1,0b0101,0, "vabal", "u", int_arm_neon_vabalu>;
 
2234
 
 
2235
// Vector Maximum and Minimum.
 
2236
 
 
2237
//   VMAX     : Vector Maximum
 
2238
defm VMAXs    : N3VInt_QHS<0,0,0b0110,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2239
                           IIC_VBINi4Q, "vmax", "s", int_arm_neon_vmaxs, 1>;
 
2240
defm VMAXu    : N3VInt_QHS<1,0,0b0110,0, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2241
                           IIC_VBINi4Q, "vmax", "u", int_arm_neon_vmaxu, 1>;
 
2242
def  VMAXfd   : N3VDInt<0, 0, 0b00, 0b1111, 0, IIC_VBIND, "vmax", "f32",
 
2243
                        v2f32, v2f32, int_arm_neon_vmaxs, 1>;
 
2244
def  VMAXfq   : N3VQInt<0, 0, 0b00, 0b1111, 0, IIC_VBINQ, "vmax", "f32",
 
2245
                        v4f32, v4f32, int_arm_neon_vmaxs, 1>;
 
2246
 
 
2247
//   VMIN     : Vector Minimum
 
2248
defm VMINs    : N3VInt_QHS<0,0,0b0110,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2249
                           IIC_VBINi4Q, "vmin", "s", int_arm_neon_vmins, 1>;
 
2250
defm VMINu    : N3VInt_QHS<1,0,0b0110,1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
 
2251
                           IIC_VBINi4Q, "vmin", "u", int_arm_neon_vminu, 1>;
 
2252
def  VMINfd   : N3VDInt<0, 0, 0b10, 0b1111, 0, IIC_VBIND, "vmin", "f32",
 
2253
                        v2f32, v2f32, int_arm_neon_vmins, 1>;
 
2254
def  VMINfq   : N3VQInt<0, 0, 0b10, 0b1111, 0, IIC_VBINQ, "vmin", "f32",
 
2255
                        v4f32, v4f32, int_arm_neon_vmins, 1>;
 
2256
 
 
2257
// Vector Pairwise Operations.
 
2258
 
 
2259
//   VPADD    : Vector Pairwise Add
 
2260
def  VPADDi8  : N3VDInt<0, 0, 0b00, 0b1011, 1, IIC_VBINiD, "vpadd", "i8",
 
2261
                        v8i8, v8i8, int_arm_neon_vpadd, 0>;
 
2262
def  VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, IIC_VBINiD, "vpadd", "i16",
 
2263
                        v4i16, v4i16, int_arm_neon_vpadd, 0>;
 
2264
def  VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, IIC_VBINiD, "vpadd", "i32",
 
2265
                        v2i32, v2i32, int_arm_neon_vpadd, 0>;
 
2266
def  VPADDf   : N3VDInt<1, 0, 0b00, 0b1101, 0, IIC_VBIND, "vpadd", "f32",
 
2267
                        v2f32, v2f32, int_arm_neon_vpadd, 0>;
 
2268
 
 
2269
//   VPADDL   : Vector Pairwise Add Long
 
2270
defm VPADDLs  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s",
 
2271
                             int_arm_neon_vpaddls>;
 
2272
defm VPADDLu  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u",
 
2273
                             int_arm_neon_vpaddlu>;
 
2274
 
 
2275
//   VPADAL   : Vector Pairwise Add and Accumulate Long
 
2276
defm VPADALs  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s",
 
2277
                              int_arm_neon_vpadals>;
 
2278
defm VPADALu  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u",
 
2279
                              int_arm_neon_vpadalu>;
 
2280
 
 
2281
//   VPMAX    : Vector Pairwise Maximum
 
2282
def  VPMAXs8  : N3VDInt<0, 0, 0b00, 0b1010, 0, IIC_VBINi4D, "vpmax", "s8",
 
2283
                        v8i8, v8i8, int_arm_neon_vpmaxs, 0>;
 
2284
def  VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, IIC_VBINi4D, "vpmax", "s16",
 
2285
                        v4i16, v4i16, int_arm_neon_vpmaxs, 0>;
 
2286
def  VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, IIC_VBINi4D, "vpmax", "s32",
 
2287
                        v2i32, v2i32, int_arm_neon_vpmaxs, 0>;
 
2288
def  VPMAXu8  : N3VDInt<1, 0, 0b00, 0b1010, 0, IIC_VBINi4D, "vpmax", "u8",
 
2289
                        v8i8, v8i8, int_arm_neon_vpmaxu, 0>;
 
2290
def  VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, IIC_VBINi4D, "vpmax", "u16",
 
2291
                        v4i16, v4i16, int_arm_neon_vpmaxu, 0>;
 
2292
def  VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, IIC_VBINi4D, "vpmax", "u32",
 
2293
                        v2i32, v2i32, int_arm_neon_vpmaxu, 0>;
 
2294
def  VPMAXf   : N3VDInt<1, 0, 0b00, 0b1111, 0, IIC_VBINi4D, "vpmax", "f32",
 
2295
                        v2f32, v2f32, int_arm_neon_vpmaxs, 0>;
 
2296
 
 
2297
//   VPMIN    : Vector Pairwise Minimum
 
2298
def  VPMINs8  : N3VDInt<0, 0, 0b00, 0b1010, 1, IIC_VBINi4D, "vpmin", "s8",
 
2299
                        v8i8, v8i8, int_arm_neon_vpmins, 0>;
 
2300
def  VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, IIC_VBINi4D, "vpmin", "s16",
 
2301
                        v4i16, v4i16, int_arm_neon_vpmins, 0>;
 
2302
def  VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, IIC_VBINi4D, "vpmin", "s32",
 
2303
                        v2i32, v2i32, int_arm_neon_vpmins, 0>;
 
2304
def  VPMINu8  : N3VDInt<1, 0, 0b00, 0b1010, 1, IIC_VBINi4D, "vpmin", "u8",
 
2305
                        v8i8, v8i8, int_arm_neon_vpminu, 0>;
 
2306
def  VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, IIC_VBINi4D, "vpmin", "u16",
 
2307
                        v4i16, v4i16, int_arm_neon_vpminu, 0>;
 
2308
def  VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, IIC_VBINi4D, "vpmin", "u32",
 
2309
                        v2i32, v2i32, int_arm_neon_vpminu, 0>;
 
2310
def  VPMINf   : N3VDInt<1, 0, 0b10, 0b1111, 0, IIC_VBINi4D, "vpmin", "f32",
 
2311
                        v2f32, v2f32, int_arm_neon_vpmins, 0>;
 
2312
 
 
2313
// Vector Reciprocal and Reciprocal Square Root Estimate and Step.
 
2314
 
 
2315
//   VRECPE   : Vector Reciprocal Estimate
 
2316
def  VRECPEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 
 
2317
                        IIC_VUNAD, "vrecpe", "u32",
 
2318
                        v2i32, v2i32, int_arm_neon_vrecpe>;
 
2319
def  VRECPEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 
 
2320
                        IIC_VUNAQ, "vrecpe", "u32",
 
2321
                        v4i32, v4i32, int_arm_neon_vrecpe>;
 
2322
def  VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
 
2323
                        IIC_VUNAD, "vrecpe", "f32",
 
2324
                        v2f32, v2f32, int_arm_neon_vrecpe>;
 
2325
def  VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0,
 
2326
                        IIC_VUNAQ, "vrecpe", "f32",
 
2327
                        v4f32, v4f32, int_arm_neon_vrecpe>;
 
2328
 
 
2329
//   VRECPS   : Vector Reciprocal Step
 
2330
def  VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1,
 
2331
                        IIC_VRECSD, "vrecps", "f32",
 
2332
                        v2f32, v2f32, int_arm_neon_vrecps, 1>;
 
2333
def  VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1,
 
2334
                        IIC_VRECSQ, "vrecps", "f32",
 
2335
                        v4f32, v4f32, int_arm_neon_vrecps, 1>;
 
2336
 
 
2337
//   VRSQRTE  : Vector Reciprocal Square Root Estimate
 
2338
def  VRSQRTEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
 
2339
                         IIC_VUNAD, "vrsqrte", "u32",
 
2340
                         v2i32, v2i32, int_arm_neon_vrsqrte>;
 
2341
def  VRSQRTEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0,
 
2342
                         IIC_VUNAQ, "vrsqrte", "u32",
 
2343
                         v4i32, v4i32, int_arm_neon_vrsqrte>;
 
2344
def  VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0,
 
2345
                         IIC_VUNAD, "vrsqrte", "f32",
 
2346
                         v2f32, v2f32, int_arm_neon_vrsqrte>;
 
2347
def  VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, 
 
2348
                         IIC_VUNAQ, "vrsqrte", "f32",
 
2349
                         v4f32, v4f32, int_arm_neon_vrsqrte>;
 
2350
 
 
2351
//   VRSQRTS  : Vector Reciprocal Square Root Step
 
2352
def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1,
 
2353
                        IIC_VRECSD, "vrsqrts", "f32",
 
2354
                        v2f32, v2f32, int_arm_neon_vrsqrts, 1>;
 
2355
def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1,
 
2356
                        IIC_VRECSQ, "vrsqrts", "f32",
 
2357
                        v4f32, v4f32, int_arm_neon_vrsqrts, 1>;
 
2358
 
 
2359
// Vector Shifts.
 
2360
 
 
2361
//   VSHL     : Vector Shift
 
2362
defm VSHLs    : N3VInt_QHSD<0, 0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
 
2363
                            IIC_VSHLiQ, "vshl", "s", int_arm_neon_vshifts, 0>;
 
2364
defm VSHLu    : N3VInt_QHSD<1, 0, 0b0100, 0, IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ,
 
2365
                            IIC_VSHLiQ, "vshl", "u", int_arm_neon_vshiftu, 0>;
 
2366
//   VSHL     : Vector Shift Left (Immediate)
 
2367
defm VSHLi    : N2VSh_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", NEONvshl>;
 
2368
//   VSHR     : Vector Shift Right (Immediate)
 
2369
defm VSHRs    : N2VSh_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", NEONvshrs>;
 
2370
defm VSHRu    : N2VSh_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", NEONvshru>;
 
2371
 
 
2372
//   VSHLL    : Vector Shift Left Long
 
2373
defm VSHLLs   : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s", NEONvshlls>;
 
2374
defm VSHLLu   : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u", NEONvshllu>;
 
2375
 
 
2376
//   VSHLL    : Vector Shift Left Long (with maximum shift count)
 
2377
class N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 
2378
                bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy,
 
2379
                ValueType OpTy, SDNode OpNode>
 
2380
  : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt,
 
2381
           ResTy, OpTy, OpNode> {
 
2382
  let Inst{21-16} = op21_16;
 
2383
}
 
2384
def  VSHLLi8  : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8",
 
2385
                          v8i16, v8i8, NEONvshlli>;
 
2386
def  VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16",
 
2387
                          v4i32, v4i16, NEONvshlli>;
 
2388
def  VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32",
 
2389
                          v2i64, v2i32, NEONvshlli>;
 
2390
 
 
2391
//   VSHRN    : Vector Shift Right and Narrow
 
2392
defm VSHRN    : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i",
 
2393
                           NEONvshrn>;
 
2394
 
 
2395
//   VRSHL    : Vector Rounding Shift
 
2396
defm VRSHLs   : N3VInt_QHSD<0,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2397
                            IIC_VSHLi4Q, "vrshl", "s", int_arm_neon_vrshifts,0>;
 
2398
defm VRSHLu   : N3VInt_QHSD<1,0,0b0101,0, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2399
                            IIC_VSHLi4Q, "vrshl", "u", int_arm_neon_vrshiftu,0>;
 
2400
//   VRSHR    : Vector Rounding Shift Right
 
2401
defm VRSHRs   : N2VSh_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", NEONvrshrs>;
 
2402
defm VRSHRu   : N2VSh_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", NEONvrshru>;
 
2403
 
 
2404
//   VRSHRN   : Vector Rounding Shift Right and Narrow
 
2405
defm VRSHRN   : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i",
 
2406
                           NEONvrshrn>;
 
2407
 
 
2408
//   VQSHL    : Vector Saturating Shift
 
2409
defm VQSHLs   : N3VInt_QHSD<0,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2410
                            IIC_VSHLi4Q, "vqshl", "s", int_arm_neon_vqshifts,0>;
 
2411
defm VQSHLu   : N3VInt_QHSD<1,0,0b0100,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2412
                            IIC_VSHLi4Q, "vqshl", "u", int_arm_neon_vqshiftu,0>;
 
2413
//   VQSHL    : Vector Saturating Shift Left (Immediate)
 
2414
defm VQSHLsi  : N2VSh_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s", NEONvqshls>;
 
2415
defm VQSHLui  : N2VSh_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u", NEONvqshlu>;
 
2416
//   VQSHLU   : Vector Saturating Shift Left (Immediate, Unsigned)
 
2417
defm VQSHLsu  : N2VSh_QHSD<1,1,0b0110,1, IIC_VSHLi4D, "vqshlu","s",NEONvqshlsu>;
 
2418
 
 
2419
//   VQSHRN   : Vector Saturating Shift Right and Narrow
 
2420
defm VQSHRNs  : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s",
 
2421
                           NEONvqshrns>;
 
2422
defm VQSHRNu  : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u",
 
2423
                           NEONvqshrnu>;
 
2424
 
 
2425
//   VQSHRUN  : Vector Saturating Shift Right and Narrow (Unsigned)
 
2426
defm VQSHRUN  : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s",
 
2427
                           NEONvqshrnsu>;
 
2428
 
 
2429
//   VQRSHL   : Vector Saturating Rounding Shift
 
2430
defm VQRSHLs  : N3VInt_QHSD<0,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2431
                            IIC_VSHLi4Q, "vqrshl", "s",
 
2432
                            int_arm_neon_vqrshifts, 0>;
 
2433
defm VQRSHLu  : N3VInt_QHSD<1,0,0b0101,1, IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q,
 
2434
                            IIC_VSHLi4Q, "vqrshl", "u",
 
2435
                            int_arm_neon_vqrshiftu, 0>;
 
2436
 
 
2437
//   VQRSHRN  : Vector Saturating Rounding Shift Right and Narrow
 
2438
defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s",
 
2439
                           NEONvqrshrns>;
 
2440
defm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u",
 
2441
                           NEONvqrshrnu>;
 
2442
 
 
2443
//   VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned)
 
2444
defm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s",
 
2445
                           NEONvqrshrnsu>;
 
2446
 
 
2447
//   VSRA     : Vector Shift Right and Accumulate
 
2448
defm VSRAs    : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", NEONvshrs>;
 
2449
defm VSRAu    : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", NEONvshru>;
 
2450
//   VRSRA    : Vector Rounding Shift Right and Accumulate
 
2451
defm VRSRAs   : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrs>;
 
2452
defm VRSRAu   : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshru>;
 
2453
 
 
2454
//   VSLI     : Vector Shift Left and Insert
 
2455
defm VSLI     : N2VShIns_QHSD<1, 1, 0b0101, 1, "vsli", NEONvsli>;
 
2456
//   VSRI     : Vector Shift Right and Insert
 
2457
defm VSRI     : N2VShIns_QHSD<1, 1, 0b0100, 1, "vsri", NEONvsri>;
 
2458
 
 
2459
// Vector Absolute and Saturating Absolute.
 
2460
 
 
2461
//   VABS     : Vector Absolute Value
 
2462
defm VABS     : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0, 
 
2463
                           IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s",
 
2464
                           int_arm_neon_vabs>;
 
2465
def  VABSfd   : N2VDInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
 
2466
                        IIC_VUNAD, "vabs", "f32",
 
2467
                        v2f32, v2f32, int_arm_neon_vabs>;
 
2468
def  VABSfq   : N2VQInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0,
 
2469
                        IIC_VUNAQ, "vabs", "f32",
 
2470
                        v4f32, v4f32, int_arm_neon_vabs>;
 
2471
 
 
2472
//   VQABS    : Vector Saturating Absolute Value
 
2473
defm VQABS    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0, 
 
2474
                           IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s",
 
2475
                           int_arm_neon_vqabs>;
 
2476
 
 
2477
// Vector Negate.
 
2478
 
 
2479
def vneg      : PatFrag<(ops node:$in), (sub immAllZerosV, node:$in)>;
 
2480
def vneg_conv : PatFrag<(ops node:$in), (sub immAllZerosV_bc, node:$in)>;
 
2481
 
 
2482
class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
 
2483
  : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$dst), (ins DPR:$src),
 
2484
        IIC_VSHLiD, OpcodeStr, Dt, "$dst, $src", "",
 
2485
        [(set DPR:$dst, (Ty (vneg DPR:$src)))]>;
 
2486
class VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
 
2487
  : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$dst), (ins QPR:$src),
 
2488
        IIC_VSHLiD, OpcodeStr, Dt, "$dst, $src", "",
 
2489
        [(set QPR:$dst, (Ty (vneg QPR:$src)))]>;
 
2490
 
 
2491
//   VNEG     : Vector Negate
 
2492
def  VNEGs8d  : VNEGD<0b00, "vneg", "s8", v8i8>;
 
2493
def  VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>;
 
2494
def  VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>;
 
2495
def  VNEGs8q  : VNEGQ<0b00, "vneg", "s8", v16i8>;
 
2496
def  VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>;
 
2497
def  VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>;
 
2498
 
 
2499
//   VNEG     : Vector Negate (floating-point)
 
2500
def  VNEGfd   : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
 
2501
                    (outs DPR:$dst), (ins DPR:$src), IIC_VUNAD,
 
2502
                    "vneg", "f32", "$dst, $src", "",
 
2503
                    [(set DPR:$dst, (v2f32 (fneg DPR:$src)))]>;
 
2504
def  VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0,
 
2505
                    (outs QPR:$dst), (ins QPR:$src), IIC_VUNAQ,
 
2506
                    "vneg", "f32", "$dst, $src", "",
 
2507
                    [(set QPR:$dst, (v4f32 (fneg QPR:$src)))]>;
 
2508
 
 
2509
def : Pat<(v8i8 (vneg_conv DPR:$src)), (VNEGs8d DPR:$src)>;
 
2510
def : Pat<(v4i16 (vneg_conv DPR:$src)), (VNEGs16d DPR:$src)>;
 
2511
def : Pat<(v2i32 (vneg_conv DPR:$src)), (VNEGs32d DPR:$src)>;
 
2512
def : Pat<(v16i8 (vneg_conv QPR:$src)), (VNEGs8q QPR:$src)>;
 
2513
def : Pat<(v8i16 (vneg_conv QPR:$src)), (VNEGs16q QPR:$src)>;
 
2514
def : Pat<(v4i32 (vneg_conv QPR:$src)), (VNEGs32q QPR:$src)>;
 
2515
 
 
2516
//   VQNEG    : Vector Saturating Negate
 
2517
defm VQNEG    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0, 
 
2518
                           IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s",
 
2519
                           int_arm_neon_vqneg>;
 
2520
 
 
2521
// Vector Bit Counting Operations.
 
2522
 
 
2523
//   VCLS     : Vector Count Leading Sign Bits
 
2524
defm VCLS     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0, 
 
2525
                           IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s",
 
2526
                           int_arm_neon_vcls>;
 
2527
//   VCLZ     : Vector Count Leading Zeros
 
2528
defm VCLZ     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0, 
 
2529
                           IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i",
 
2530
                           int_arm_neon_vclz>;
 
2531
//   VCNT     : Vector Count One Bits
 
2532
def  VCNTd    : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, 
 
2533
                        IIC_VCNTiD, "vcnt", "8",
 
2534
                        v8i8, v8i8, int_arm_neon_vcnt>;
 
2535
def  VCNTq    : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0,
 
2536
                        IIC_VCNTiQ, "vcnt", "8",
 
2537
                        v16i8, v16i8, int_arm_neon_vcnt>;
 
2538
 
 
2539
// Vector Swap -- for disassembly only.
 
2540
def  VSWPd    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
 
2541
                     (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 
2542
                     "vswp", "$dst, $src", "", []>;
 
2543
def  VSWPq    : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
 
2544
                     (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 
2545
                     "vswp", "$dst, $src", "", []>;
 
2546
 
 
2547
// Vector Move Operations.
 
2548
 
 
2549
//   VMOV     : Vector Move (Register)
 
2550
 
 
2551
def  VMOVDneon: N3VX<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
 
2552
                    IIC_VMOVD, "vmov", "$dst, $src", "", []>;
 
2553
def  VMOVQ    : N3VX<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src),
 
2554
                    IIC_VMOVD, "vmov", "$dst, $src", "", []>;
 
2555
 
 
2556
//   VMOV     : Vector Move (Immediate)
 
2557
 
 
2558
// VMOV_get_imm8 xform function: convert build_vector to VMOV.i8 imm.
 
2559
def VMOV_get_imm8 : SDNodeXForm<build_vector, [{
 
2560
  return ARM::getVMOVImm(N, 1, *CurDAG);
 
2561
}]>;
 
2562
def vmovImm8 : PatLeaf<(build_vector), [{
 
2563
  return ARM::getVMOVImm(N, 1, *CurDAG).getNode() != 0;
 
2564
}], VMOV_get_imm8>;
 
2565
 
 
2566
// VMOV_get_imm16 xform function: convert build_vector to VMOV.i16 imm.
 
2567
def VMOV_get_imm16 : SDNodeXForm<build_vector, [{
 
2568
  return ARM::getVMOVImm(N, 2, *CurDAG);
 
2569
}]>;
 
2570
def vmovImm16 : PatLeaf<(build_vector), [{
 
2571
  return ARM::getVMOVImm(N, 2, *CurDAG).getNode() != 0;
 
2572
}], VMOV_get_imm16>;
 
2573
 
 
2574
// VMOV_get_imm32 xform function: convert build_vector to VMOV.i32 imm.
 
2575
def VMOV_get_imm32 : SDNodeXForm<build_vector, [{
 
2576
  return ARM::getVMOVImm(N, 4, *CurDAG);
 
2577
}]>;
 
2578
def vmovImm32 : PatLeaf<(build_vector), [{
 
2579
  return ARM::getVMOVImm(N, 4, *CurDAG).getNode() != 0;
 
2580
}], VMOV_get_imm32>;
 
2581
 
 
2582
// VMOV_get_imm64 xform function: convert build_vector to VMOV.i64 imm.
 
2583
def VMOV_get_imm64 : SDNodeXForm<build_vector, [{
 
2584
  return ARM::getVMOVImm(N, 8, *CurDAG);
 
2585
}]>;
 
2586
def vmovImm64 : PatLeaf<(build_vector), [{
 
2587
  return ARM::getVMOVImm(N, 8, *CurDAG).getNode() != 0;
 
2588
}], VMOV_get_imm64>;
 
2589
 
 
2590
// Note: Some of the cmode bits in the following VMOV instructions need to
 
2591
// be encoded based on the immed values.
 
2592
 
 
2593
def VMOVv8i8  : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$dst),
 
2594
                         (ins h8imm:$SIMM), IIC_VMOVImm,
 
2595
                         "vmov", "i8", "$dst, $SIMM", "",
 
2596
                         [(set DPR:$dst, (v8i8 vmovImm8:$SIMM))]>;
 
2597
def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$dst),
 
2598
                         (ins h8imm:$SIMM), IIC_VMOVImm,
 
2599
                         "vmov", "i8", "$dst, $SIMM", "",
 
2600
                         [(set QPR:$dst, (v16i8 vmovImm8:$SIMM))]>;
 
2601
 
 
2602
def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,?}, 0, 0, {?}, 1, (outs DPR:$dst),
 
2603
                         (ins h16imm:$SIMM), IIC_VMOVImm,
 
2604
                         "vmov", "i16", "$dst, $SIMM", "",
 
2605
                         [(set DPR:$dst, (v4i16 vmovImm16:$SIMM))]>;
 
2606
def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,?}, 0, 1, {?}, 1, (outs QPR:$dst),
 
2607
                         (ins h16imm:$SIMM), IIC_VMOVImm,
 
2608
                         "vmov", "i16", "$dst, $SIMM", "",
 
2609
                         [(set QPR:$dst, (v8i16 vmovImm16:$SIMM))]>;
 
2610
 
 
2611
def VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, {?}, 1, (outs DPR:$dst),
 
2612
                         (ins h32imm:$SIMM), IIC_VMOVImm,
 
2613
                         "vmov", "i32", "$dst, $SIMM", "",
 
2614
                         [(set DPR:$dst, (v2i32 vmovImm32:$SIMM))]>;
 
2615
def VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, {?}, 1, (outs QPR:$dst),
 
2616
                         (ins h32imm:$SIMM), IIC_VMOVImm,
 
2617
                         "vmov", "i32", "$dst, $SIMM", "",
 
2618
                         [(set QPR:$dst, (v4i32 vmovImm32:$SIMM))]>;
 
2619
 
 
2620
def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$dst),
 
2621
                         (ins h64imm:$SIMM), IIC_VMOVImm,
 
2622
                         "vmov", "i64", "$dst, $SIMM", "",
 
2623
                         [(set DPR:$dst, (v1i64 vmovImm64:$SIMM))]>;
 
2624
def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$dst),
 
2625
                         (ins h64imm:$SIMM), IIC_VMOVImm,
 
2626
                         "vmov", "i64", "$dst, $SIMM", "",
 
2627
                         [(set QPR:$dst, (v2i64 vmovImm64:$SIMM))]>;
 
2628
 
 
2629
//   VMOV     : Vector Get Lane (move scalar to ARM core register)
 
2630
 
 
2631
def VGETLNs8  : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?},
 
2632
                          (outs GPR:$dst), (ins DPR:$src, nohash_imm:$lane),
 
2633
                          IIC_VMOVSI, "vmov", "s8", "$dst, $src[$lane]",
 
2634
                          [(set GPR:$dst, (NEONvgetlanes (v8i8 DPR:$src),
 
2635
                                           imm:$lane))]>;
 
2636
def VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1},
 
2637
                          (outs GPR:$dst), (ins DPR:$src, nohash_imm:$lane),
 
2638
                          IIC_VMOVSI, "vmov", "s16", "$dst, $src[$lane]",
 
2639
                          [(set GPR:$dst, (NEONvgetlanes (v4i16 DPR:$src),
 
2640
                                           imm:$lane))]>;
 
2641
def VGETLNu8  : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?},
 
2642
                          (outs GPR:$dst), (ins DPR:$src, nohash_imm:$lane),
 
2643
                          IIC_VMOVSI, "vmov", "u8", "$dst, $src[$lane]",
 
2644
                          [(set GPR:$dst, (NEONvgetlaneu (v8i8 DPR:$src),
 
2645
                                           imm:$lane))]>;
 
2646
def VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1},
 
2647
                          (outs GPR:$dst), (ins DPR:$src, nohash_imm:$lane),
 
2648
                          IIC_VMOVSI, "vmov", "u16", "$dst, $src[$lane]",
 
2649
                          [(set GPR:$dst, (NEONvgetlaneu (v4i16 DPR:$src),
 
2650
                                           imm:$lane))]>;
 
2651
def VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00,
 
2652
                          (outs GPR:$dst), (ins DPR:$src, nohash_imm:$lane),
 
2653
                          IIC_VMOVSI, "vmov", "32", "$dst, $src[$lane]",
 
2654
                          [(set GPR:$dst, (extractelt (v2i32 DPR:$src),
 
2655
                                           imm:$lane))]>;
 
2656
// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td
 
2657
def : Pat<(NEONvgetlanes (v16i8 QPR:$src), imm:$lane),
 
2658
          (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src,
 
2659
                           (DSubReg_i8_reg imm:$lane))),
 
2660
                     (SubReg_i8_lane imm:$lane))>;
 
2661
def : Pat<(NEONvgetlanes (v8i16 QPR:$src), imm:$lane),
 
2662
          (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src,
 
2663
                             (DSubReg_i16_reg imm:$lane))),
 
2664
                     (SubReg_i16_lane imm:$lane))>;
 
2665
def : Pat<(NEONvgetlaneu (v16i8 QPR:$src), imm:$lane),
 
2666
          (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src,
 
2667
                           (DSubReg_i8_reg imm:$lane))),
 
2668
                     (SubReg_i8_lane imm:$lane))>;
 
2669
def : Pat<(NEONvgetlaneu (v8i16 QPR:$src), imm:$lane),
 
2670
          (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src,
 
2671
                             (DSubReg_i16_reg imm:$lane))),
 
2672
                     (SubReg_i16_lane imm:$lane))>;
 
2673
def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane),
 
2674
          (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src,
 
2675
                             (DSubReg_i32_reg imm:$lane))),
 
2676
                     (SubReg_i32_lane imm:$lane))>;
 
2677
def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2),
 
2678
          (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)),
 
2679
                          (SSubReg_f32_reg imm:$src2))>;
 
2680
def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2),
 
2681
          (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)),
 
2682
                          (SSubReg_f32_reg imm:$src2))>;
 
2683
//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2),
 
2684
//          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
 
2685
def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2),
 
2686
          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>;
 
2687
 
 
2688
 
 
2689
//   VMOV     : Vector Set Lane (move ARM core register to scalar)
 
2690
 
 
2691
let Constraints = "$src1 = $dst" in {
 
2692
def VSETLNi8  : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$dst),
 
2693
                          (ins DPR:$src1, GPR:$src2, nohash_imm:$lane),
 
2694
                          IIC_VMOVISL, "vmov", "8", "$dst[$lane], $src2",
 
2695
                          [(set DPR:$dst, (vector_insert (v8i8 DPR:$src1),
 
2696
                                           GPR:$src2, imm:$lane))]>;
 
2697
def VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$dst),
 
2698
                          (ins DPR:$src1, GPR:$src2, nohash_imm:$lane),
 
2699
                          IIC_VMOVISL, "vmov", "16", "$dst[$lane], $src2",
 
2700
                          [(set DPR:$dst, (vector_insert (v4i16 DPR:$src1),
 
2701
                                           GPR:$src2, imm:$lane))]>;
 
2702
def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$dst),
 
2703
                          (ins DPR:$src1, GPR:$src2, nohash_imm:$lane),
 
2704
                          IIC_VMOVISL, "vmov", "32", "$dst[$lane], $src2",
 
2705
                          [(set DPR:$dst, (insertelt (v2i32 DPR:$src1),
 
2706
                                           GPR:$src2, imm:$lane))]>;
 
2707
}
 
2708
def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane),
 
2709
          (v16i8 (INSERT_SUBREG QPR:$src1, 
 
2710
                  (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,
 
2711
                                   (DSubReg_i8_reg imm:$lane))),
 
2712
                            GPR:$src2, (SubReg_i8_lane imm:$lane)),
 
2713
                  (DSubReg_i8_reg imm:$lane)))>;
 
2714
def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane),
 
2715
          (v8i16 (INSERT_SUBREG QPR:$src1, 
 
2716
                  (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,
 
2717
                                     (DSubReg_i16_reg imm:$lane))),
 
2718
                             GPR:$src2, (SubReg_i16_lane imm:$lane)),
 
2719
                  (DSubReg_i16_reg imm:$lane)))>;
 
2720
def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane),
 
2721
          (v4i32 (INSERT_SUBREG QPR:$src1, 
 
2722
                  (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,
 
2723
                                     (DSubReg_i32_reg imm:$lane))),
 
2724
                             GPR:$src2, (SubReg_i32_lane imm:$lane)),
 
2725
                  (DSubReg_i32_reg imm:$lane)))>;
 
2726
 
 
2727
def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)),
 
2728
          (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)),
 
2729
                                SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
 
2730
def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)),
 
2731
          (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)),
 
2732
                                SPR:$src2, (SSubReg_f32_reg imm:$src3))>;
 
2733
 
 
2734
//def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
 
2735
//          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
 
2736
def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
 
2737
          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>;
 
2738
 
 
2739
def : Pat<(v2f32 (scalar_to_vector SPR:$src)),
 
2740
          (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>;
 
2741
def : Pat<(v2f64 (scalar_to_vector DPR:$src)),
 
2742
          (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, arm_dsubreg_0)>;
 
2743
def : Pat<(v4f32 (scalar_to_vector SPR:$src)),
 
2744
          (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>;
 
2745
 
 
2746
def : Pat<(v8i8 (scalar_to_vector GPR:$src)),
 
2747
          (VSETLNi8  (v8i8  (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
 
2748
def : Pat<(v4i16 (scalar_to_vector GPR:$src)),
 
2749
          (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
 
2750
def : Pat<(v2i32 (scalar_to_vector GPR:$src)),
 
2751
          (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>;
 
2752
 
 
2753
def : Pat<(v16i8 (scalar_to_vector GPR:$src)),
 
2754
          (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
 
2755
                         (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
 
2756
                         arm_dsubreg_0)>;
 
2757
def : Pat<(v8i16 (scalar_to_vector GPR:$src)),
 
2758
          (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)),
 
2759
                         (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
 
2760
                         arm_dsubreg_0)>;
 
2761
def : Pat<(v4i32 (scalar_to_vector GPR:$src)),
 
2762
          (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
 
2763
                         (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)),
 
2764
                         arm_dsubreg_0)>;
 
2765
 
 
2766
//   VDUP     : Vector Duplicate (from ARM core register to all elements)
 
2767
 
 
2768
class VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
 
2769
  : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$dst), (ins GPR:$src),
 
2770
          IIC_VMOVIS, "vdup", Dt, "$dst, $src",
 
2771
          [(set DPR:$dst, (Ty (NEONvdup (i32 GPR:$src))))]>;
 
2772
class VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty>
 
2773
  : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$dst), (ins GPR:$src),
 
2774
          IIC_VMOVIS, "vdup", Dt, "$dst, $src",
 
2775
          [(set QPR:$dst, (Ty (NEONvdup (i32 GPR:$src))))]>;
 
2776
 
 
2777
def  VDUP8d   : VDUPD<0b11101100, 0b00, "8", v8i8>;
 
2778
def  VDUP16d  : VDUPD<0b11101000, 0b01, "16", v4i16>;
 
2779
def  VDUP32d  : VDUPD<0b11101000, 0b00, "32", v2i32>;
 
2780
def  VDUP8q   : VDUPQ<0b11101110, 0b00, "8", v16i8>;
 
2781
def  VDUP16q  : VDUPQ<0b11101010, 0b01, "16", v8i16>;
 
2782
def  VDUP32q  : VDUPQ<0b11101010, 0b00, "32", v4i32>;
 
2783
 
 
2784
def  VDUPfd   : NVDup<0b11101000, 0b1011, 0b00, (outs DPR:$dst), (ins GPR:$src),
 
2785
                      IIC_VMOVIS, "vdup", "32", "$dst, $src",
 
2786
                      [(set DPR:$dst, (v2f32 (NEONvdup
 
2787
                                              (f32 (bitconvert GPR:$src)))))]>;
 
2788
def  VDUPfq   : NVDup<0b11101010, 0b1011, 0b00, (outs QPR:$dst), (ins GPR:$src),
 
2789
                      IIC_VMOVIS, "vdup", "32", "$dst, $src",
 
2790
                      [(set QPR:$dst, (v4f32 (NEONvdup
 
2791
                                              (f32 (bitconvert GPR:$src)))))]>;
 
2792
 
 
2793
//   VDUP     : Vector Duplicate Lane (from scalar to all elements)
 
2794
 
 
2795
class VDUPLND<bits<2> op19_18, bits<2> op17_16,
 
2796
              string OpcodeStr, string Dt, ValueType Ty>
 
2797
  : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 0, 0,
 
2798
        (outs DPR:$dst), (ins DPR:$src, nohash_imm:$lane), IIC_VMOVD,
 
2799
        OpcodeStr, Dt, "$dst, $src[$lane]", "",
 
2800
        [(set DPR:$dst, (Ty (NEONvduplane (Ty DPR:$src), imm:$lane)))]>;
 
2801
 
 
2802
class VDUPLNQ<bits<2> op19_18, bits<2> op17_16, string OpcodeStr, string Dt,
 
2803
              ValueType ResTy, ValueType OpTy>
 
2804
  : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 1, 0,
 
2805
        (outs QPR:$dst), (ins DPR:$src, nohash_imm:$lane), IIC_VMOVD,
 
2806
        OpcodeStr, Dt, "$dst, $src[$lane]", "",
 
2807
        [(set QPR:$dst, (ResTy (NEONvduplane (OpTy DPR:$src), imm:$lane)))]>;
 
2808
 
 
2809
// Inst{19-16} is partially specified depending on the element size.
 
2810
 
 
2811
def VDUPLN8d  : VDUPLND<{?,?}, {?,1}, "vdup", "8", v8i8>;
 
2812
def VDUPLN16d : VDUPLND<{?,?}, {1,0}, "vdup", "16", v4i16>;
 
2813
def VDUPLN32d : VDUPLND<{?,1}, {0,0}, "vdup", "32", v2i32>;
 
2814
def VDUPLNfd  : VDUPLND<{?,1}, {0,0}, "vdup", "32", v2f32>;
 
2815
def VDUPLN8q  : VDUPLNQ<{?,?}, {?,1}, "vdup", "8", v16i8, v8i8>;
 
2816
def VDUPLN16q : VDUPLNQ<{?,?}, {1,0}, "vdup", "16", v8i16, v4i16>;
 
2817
def VDUPLN32q : VDUPLNQ<{?,1}, {0,0}, "vdup", "32", v4i32, v2i32>;
 
2818
def VDUPLNfq  : VDUPLNQ<{?,1}, {0,0}, "vdup", "32", v4f32, v2f32>;
 
2819
 
 
2820
def : Pat<(v16i8 (NEONvduplane (v16i8 QPR:$src), imm:$lane)),
 
2821
          (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src,
 
2822
                                  (DSubReg_i8_reg imm:$lane))),
 
2823
                           (SubReg_i8_lane imm:$lane)))>;
 
2824
def : Pat<(v8i16 (NEONvduplane (v8i16 QPR:$src), imm:$lane)),
 
2825
          (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src,
 
2826
                                    (DSubReg_i16_reg imm:$lane))),
 
2827
                            (SubReg_i16_lane imm:$lane)))>;
 
2828
def : Pat<(v4i32 (NEONvduplane (v4i32 QPR:$src), imm:$lane)),
 
2829
          (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src,
 
2830
                                    (DSubReg_i32_reg imm:$lane))),
 
2831
                            (SubReg_i32_lane imm:$lane)))>;
 
2832
def : Pat<(v4f32 (NEONvduplane (v4f32 QPR:$src), imm:$lane)),
 
2833
          (v4f32 (VDUPLNfq (v2f32 (EXTRACT_SUBREG QPR:$src,
 
2834
                                   (DSubReg_i32_reg imm:$lane))),
 
2835
                           (SubReg_i32_lane imm:$lane)))>;
 
2836
 
 
2837
def  VDUPfdf  : N2V<0b11, 0b11, {?,1}, {0,0}, 0b11000, 0, 0,
 
2838
                    (outs DPR:$dst), (ins SPR:$src),
 
2839
                    IIC_VMOVD, "vdup", "32", "$dst, ${src:lane}", "",
 
2840
                    [(set DPR:$dst, (v2f32 (NEONvdup (f32 SPR:$src))))]>;
 
2841
 
 
2842
def  VDUPfqf  : N2V<0b11, 0b11, {?,1}, {0,0}, 0b11000, 1, 0,
 
2843
                    (outs QPR:$dst), (ins SPR:$src),
 
2844
                    IIC_VMOVD, "vdup", "32", "$dst, ${src:lane}", "",
 
2845
                    [(set QPR:$dst, (v4f32 (NEONvdup (f32 SPR:$src))))]>;
 
2846
 
 
2847
def : Pat<(v2i64 (NEONvduplane (v2i64 QPR:$src), imm:$lane)),
 
2848
          (INSERT_SUBREG QPR:$src, 
 
2849
                         (i64 (EXTRACT_SUBREG QPR:$src,
 
2850
                               (DSubReg_f64_reg imm:$lane))),
 
2851
                         (DSubReg_f64_other_reg imm:$lane))>;
 
2852
def : Pat<(v2f64 (NEONvduplane (v2f64 QPR:$src), imm:$lane)),
 
2853
          (INSERT_SUBREG QPR:$src, 
 
2854
                         (f64 (EXTRACT_SUBREG QPR:$src,
 
2855
                               (DSubReg_f64_reg imm:$lane))),
 
2856
                         (DSubReg_f64_other_reg imm:$lane))>;
 
2857
 
 
2858
//   VMOVN    : Vector Narrowing Move
 
2859
defm VMOVN    : N2VNInt_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVD,
 
2860
                            "vmovn", "i", int_arm_neon_vmovn>;
 
2861
//   VQMOVN   : Vector Saturating Narrowing Move
 
2862
defm VQMOVNs  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD,
 
2863
                            "vqmovn", "s", int_arm_neon_vqmovns>;
 
2864
defm VQMOVNu  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD,
 
2865
                            "vqmovn", "u", int_arm_neon_vqmovnu>;
 
2866
defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD,
 
2867
                            "vqmovun", "s", int_arm_neon_vqmovnsu>;
 
2868
//   VMOVL    : Vector Lengthening Move
 
2869
defm VMOVLs   : N2VLInt_QHS<0b01,0b10100,0,1, "vmovl", "s",
 
2870
                            int_arm_neon_vmovls>;
 
2871
defm VMOVLu   : N2VLInt_QHS<0b11,0b10100,0,1, "vmovl", "u",
 
2872
                            int_arm_neon_vmovlu>;
 
2873
 
 
2874
// Vector Conversions.
 
2875
 
 
2876
//   VCVT     : Vector Convert Between Floating-Point and Integers
 
2877
def  VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
 
2878
                     v2i32, v2f32, fp_to_sint>;
 
2879
def  VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
 
2880
                     v2i32, v2f32, fp_to_uint>;
 
2881
def  VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
 
2882
                     v2f32, v2i32, sint_to_fp>;
 
2883
def  VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
 
2884
                     v2f32, v2i32, uint_to_fp>;
 
2885
 
 
2886
def  VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
 
2887
                     v4i32, v4f32, fp_to_sint>;
 
2888
def  VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
 
2889
                     v4i32, v4f32, fp_to_uint>;
 
2890
def  VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
 
2891
                     v4f32, v4i32, sint_to_fp>;
 
2892
def  VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
 
2893
                     v4f32, v4i32, uint_to_fp>;
 
2894
 
 
2895
//   VCVT     : Vector Convert Between Floating-Point and Fixed-Point.
 
2896
def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
 
2897
                        v2i32, v2f32, int_arm_neon_vcvtfp2fxs>;
 
2898
def VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
 
2899
                        v2i32, v2f32, int_arm_neon_vcvtfp2fxu>;
 
2900
def VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
 
2901
                        v2f32, v2i32, int_arm_neon_vcvtfxs2fp>;
 
2902
def VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
 
2903
                        v2f32, v2i32, int_arm_neon_vcvtfxu2fp>;
 
2904
 
 
2905
def VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32",
 
2906
                        v4i32, v4f32, int_arm_neon_vcvtfp2fxs>;
 
2907
def VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32",
 
2908
                        v4i32, v4f32, int_arm_neon_vcvtfp2fxu>;
 
2909
def VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32",
 
2910
                        v4f32, v4i32, int_arm_neon_vcvtfxs2fp>;
 
2911
def VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32",
 
2912
                        v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;
 
2913
 
 
2914
// Vector Reverse.
 
2915
 
 
2916
//   VREV64   : Vector Reverse elements within 64-bit doublewords
 
2917
 
 
2918
class VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2919
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$dst),
 
2920
        (ins DPR:$src), IIC_VMOVD, 
 
2921
        OpcodeStr, Dt, "$dst, $src", "",
 
2922
        [(set DPR:$dst, (Ty (NEONvrev64 (Ty DPR:$src))))]>;
 
2923
class VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2924
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$dst),
 
2925
        (ins QPR:$src), IIC_VMOVD, 
 
2926
        OpcodeStr, Dt, "$dst, $src", "",
 
2927
        [(set QPR:$dst, (Ty (NEONvrev64 (Ty QPR:$src))))]>;
 
2928
 
 
2929
def VREV64d8  : VREV64D<0b00, "vrev64", "8", v8i8>;
 
2930
def VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>;
 
2931
def VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>;
 
2932
def VREV64df  : VREV64D<0b10, "vrev64", "32", v2f32>;
 
2933
 
 
2934
def VREV64q8  : VREV64Q<0b00, "vrev64", "8", v16i8>;
 
2935
def VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>;
 
2936
def VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>;
 
2937
def VREV64qf  : VREV64Q<0b10, "vrev64", "32", v4f32>;
 
2938
 
 
2939
//   VREV32   : Vector Reverse elements within 32-bit words
 
2940
 
 
2941
class VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2942
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$dst),
 
2943
        (ins DPR:$src), IIC_VMOVD, 
 
2944
        OpcodeStr, Dt, "$dst, $src", "",
 
2945
        [(set DPR:$dst, (Ty (NEONvrev32 (Ty DPR:$src))))]>;
 
2946
class VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2947
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$dst),
 
2948
        (ins QPR:$src), IIC_VMOVD, 
 
2949
        OpcodeStr, Dt, "$dst, $src", "",
 
2950
        [(set QPR:$dst, (Ty (NEONvrev32 (Ty QPR:$src))))]>;
 
2951
 
 
2952
def VREV32d8  : VREV32D<0b00, "vrev32", "8", v8i8>;
 
2953
def VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>;
 
2954
 
 
2955
def VREV32q8  : VREV32Q<0b00, "vrev32", "8", v16i8>;
 
2956
def VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>;
 
2957
 
 
2958
//   VREV16   : Vector Reverse elements within 16-bit halfwords
 
2959
 
 
2960
class VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2961
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$dst),
 
2962
        (ins DPR:$src), IIC_VMOVD, 
 
2963
        OpcodeStr, Dt, "$dst, $src", "",
 
2964
        [(set DPR:$dst, (Ty (NEONvrev16 (Ty DPR:$src))))]>;
 
2965
class VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty>
 
2966
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$dst),
 
2967
        (ins QPR:$src), IIC_VMOVD, 
 
2968
        OpcodeStr, Dt, "$dst, $src", "",
 
2969
        [(set QPR:$dst, (Ty (NEONvrev16 (Ty QPR:$src))))]>;
 
2970
 
 
2971
def VREV16d8  : VREV16D<0b00, "vrev16", "8", v8i8>;
 
2972
def VREV16q8  : VREV16Q<0b00, "vrev16", "8", v16i8>;
 
2973
 
 
2974
// Other Vector Shuffles.
 
2975
 
 
2976
//   VEXT     : Vector Extract
 
2977
 
 
2978
class VEXTd<string OpcodeStr, string Dt, ValueType Ty>
 
2979
  : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$dst),
 
2980
        (ins DPR:$lhs, DPR:$rhs, i32imm:$index), IIC_VEXTD,
 
2981
        OpcodeStr, Dt, "$dst, $lhs, $rhs, $index", "",
 
2982
        [(set DPR:$dst, (Ty (NEONvext (Ty DPR:$lhs),
 
2983
                                      (Ty DPR:$rhs), imm:$index)))]>;
 
2984
 
 
2985
class VEXTq<string OpcodeStr, string Dt, ValueType Ty>
 
2986
  : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$dst),
 
2987
        (ins QPR:$lhs, QPR:$rhs, i32imm:$index), IIC_VEXTQ,
 
2988
        OpcodeStr, Dt, "$dst, $lhs, $rhs, $index", "",
 
2989
        [(set QPR:$dst, (Ty (NEONvext (Ty QPR:$lhs),
 
2990
                                      (Ty QPR:$rhs), imm:$index)))]>;
 
2991
 
 
2992
def VEXTd8  : VEXTd<"vext", "8",  v8i8>;
 
2993
def VEXTd16 : VEXTd<"vext", "16", v4i16>;
 
2994
def VEXTd32 : VEXTd<"vext", "32", v2i32>;
 
2995
def VEXTdf  : VEXTd<"vext", "32", v2f32>;
 
2996
 
 
2997
def VEXTq8  : VEXTq<"vext", "8",  v16i8>;
 
2998
def VEXTq16 : VEXTq<"vext", "16", v8i16>;
 
2999
def VEXTq32 : VEXTq<"vext", "32", v4i32>;
 
3000
def VEXTqf  : VEXTq<"vext", "32", v4f32>;
 
3001
 
 
3002
//   VTRN     : Vector Transpose
 
3003
 
 
3004
def  VTRNd8   : N2VDShuffle<0b00, 0b00001, "vtrn", "8">;
 
3005
def  VTRNd16  : N2VDShuffle<0b01, 0b00001, "vtrn", "16">;
 
3006
def  VTRNd32  : N2VDShuffle<0b10, 0b00001, "vtrn", "32">;
 
3007
 
 
3008
def  VTRNq8   : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">;
 
3009
def  VTRNq16  : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">;
 
3010
def  VTRNq32  : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">;
 
3011
 
 
3012
//   VUZP     : Vector Unzip (Deinterleave)
 
3013
 
 
3014
def  VUZPd8   : N2VDShuffle<0b00, 0b00010, "vuzp", "8">;
 
3015
def  VUZPd16  : N2VDShuffle<0b01, 0b00010, "vuzp", "16">;
 
3016
def  VUZPd32  : N2VDShuffle<0b10, 0b00010, "vuzp", "32">;
 
3017
 
 
3018
def  VUZPq8   : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">;
 
3019
def  VUZPq16  : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">;
 
3020
def  VUZPq32  : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">;
 
3021
 
 
3022
//   VZIP     : Vector Zip (Interleave)
 
3023
 
 
3024
def  VZIPd8   : N2VDShuffle<0b00, 0b00011, "vzip", "8">;
 
3025
def  VZIPd16  : N2VDShuffle<0b01, 0b00011, "vzip", "16">;
 
3026
def  VZIPd32  : N2VDShuffle<0b10, 0b00011, "vzip", "32">;
 
3027
 
 
3028
def  VZIPq8   : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">;
 
3029
def  VZIPq16  : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">;
 
3030
def  VZIPq32  : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">;
 
3031
 
 
3032
// Vector Table Lookup and Table Extension.
 
3033
 
 
3034
//   VTBL     : Vector Table Lookup
 
3035
def  VTBL1
 
3036
  : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$dst),
 
3037
        (ins DPR:$tbl1, DPR:$src), IIC_VTB1,
 
3038
        "vtbl", "8", "$dst, \\{$tbl1\\}, $src", "",
 
3039
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl1 DPR:$tbl1, DPR:$src)))]>;
 
3040
let hasExtraSrcRegAllocReq = 1 in {
 
3041
def  VTBL2
 
3042
  : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$dst),
 
3043
        (ins DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTB2,
 
3044
        "vtbl", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "",
 
3045
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl2
 
3046
                               DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
 
3047
def  VTBL3
 
3048
  : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$dst),
 
3049
        (ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTB3,
 
3050
        "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "",
 
3051
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl3
 
3052
                               DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
 
3053
def  VTBL4
 
3054
  : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$dst),
 
3055
        (ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTB4,
 
3056
        "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src", "",
 
3057
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl4 DPR:$tbl1, DPR:$tbl2,
 
3058
                               DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
 
3059
} // hasExtraSrcRegAllocReq = 1
 
3060
 
 
3061
//   VTBX     : Vector Table Extension
 
3062
def  VTBX1
 
3063
  : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$dst),
 
3064
        (ins DPR:$orig, DPR:$tbl1, DPR:$src), IIC_VTBX1,
 
3065
        "vtbx", "8", "$dst, \\{$tbl1\\}, $src", "$orig = $dst",
 
3066
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx1
 
3067
                               DPR:$orig, DPR:$tbl1, DPR:$src)))]>;
 
3068
let hasExtraSrcRegAllocReq = 1 in {
 
3069
def  VTBX2
 
3070
  : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$dst),
 
3071
        (ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTBX2,
 
3072
        "vtbx", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "$orig = $dst",
 
3073
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx2
 
3074
                               DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
 
3075
def  VTBX3
 
3076
  : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$dst),
 
3077
        (ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTBX3,
 
3078
        "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "$orig = $dst",
 
3079
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx3 DPR:$orig, DPR:$tbl1,
 
3080
                               DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
 
3081
def  VTBX4
 
3082
  : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$dst), (ins DPR:$orig, DPR:$tbl1,
 
3083
        DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTBX4,
 
3084
        "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src",
 
3085
        "$orig = $dst",
 
3086
        [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx4 DPR:$orig, DPR:$tbl1,
 
3087
                               DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
 
3088
} // hasExtraSrcRegAllocReq = 1
 
3089
 
 
3090
//===----------------------------------------------------------------------===//
 
3091
// NEON instructions for single-precision FP math
 
3092
//===----------------------------------------------------------------------===//
 
3093
 
 
3094
class N2VSPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst>
 
3095
  : NEONFPPat<(ResTy (OpNode SPR:$a)),
 
3096
              (EXTRACT_SUBREG (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)),
 
3097
                                                   SPR:$a, arm_ssubreg_0)),
 
3098
                              arm_ssubreg_0)>;
 
3099
 
 
3100
class N3VSPat<SDNode OpNode, NeonI Inst>
 
3101
  : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
 
3102
              (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
 
3103
                                                   SPR:$a, arm_ssubreg_0),
 
3104
                                    (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
 
3105
                                                   SPR:$b, arm_ssubreg_0)),
 
3106
                              arm_ssubreg_0)>;
 
3107
 
 
3108
class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>
 
3109
  : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))),
 
3110
              (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
 
3111
                                                   SPR:$acc, arm_ssubreg_0),
 
3112
                                    (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
 
3113
                                                   SPR:$a, arm_ssubreg_0),
 
3114
                                    (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
 
3115
                                                   SPR:$b, arm_ssubreg_0)),
 
3116
                              arm_ssubreg_0)>;
 
3117
 
 
3118
// These need separate instructions because they must use DPR_VFP2 register
 
3119
// class which have SPR sub-registers.
 
3120
 
 
3121
// Vector Add Operations used for single-precision FP
 
3122
let neverHasSideEffects = 1 in
 
3123
def VADDfd_sfp : N3VS<0,0,0b00,0b1101,0, "vadd", "f32", v2f32, v2f32, fadd, 1>;
 
3124
def : N3VSPat<fadd, VADDfd_sfp>;
 
3125
 
 
3126
// Vector Sub Operations used for single-precision FP
 
3127
let neverHasSideEffects = 1 in
 
3128
def VSUBfd_sfp : N3VS<0,0,0b10,0b1101,0, "vsub", "f32", v2f32, v2f32, fsub, 0>;
 
3129
def : N3VSPat<fsub, VSUBfd_sfp>;
 
3130
 
 
3131
// Vector Multiply Operations used for single-precision FP
 
3132
let neverHasSideEffects = 1 in
 
3133
def VMULfd_sfp : N3VS<1,0,0b00,0b1101,1, "vmul", "f32", v2f32, v2f32, fmul, 1>;
 
3134
def : N3VSPat<fmul, VMULfd_sfp>;
 
3135
 
 
3136
// Vector Multiply-Accumulate/Subtract used for single-precision FP
 
3137
// vml[as].f32 can cause 4-8 cycle stalls in following ASIMD instructions, so
 
3138
// we want to avoid them for now. e.g., alternating vmla/vadd instructions.
 
3139
 
 
3140
//let neverHasSideEffects = 1 in
 
3141
//def VMLAfd_sfp : N3VSMulOp<0,0,0b00,0b1101,1, IIC_VMACD, "vmla", "f32",
 
3142
//                            v2f32, fmul, fadd>;
 
3143
//def : N3VSMulOpPat<fmul, fadd, VMLAfd_sfp>;
 
3144
 
 
3145
//let neverHasSideEffects = 1 in
 
3146
//def VMLSfd_sfp : N3VSMulOp<0,0,0b10,0b1101,1, IIC_VMACD, "vmls", "f32",
 
3147
//                            v2f32, fmul, fsub>;
 
3148
//def : N3VSMulOpPat<fmul, fsub, VMLSfd_sfp>;
 
3149
 
 
3150
// Vector Absolute used for single-precision FP
 
3151
let neverHasSideEffects = 1 in
 
3152
def  VABSfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 0,
 
3153
                      (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), IIC_VUNAD,
 
3154
                      "vabs", "f32", "$dst, $src", "", []>;
 
3155
def : N2VSPat<fabs, f32, v2f32, VABSfd_sfp>;
 
3156
 
 
3157
// Vector Negate used for single-precision FP
 
3158
let neverHasSideEffects = 1 in
 
3159
def  VNEGfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
 
3160
                      (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), IIC_VUNAD,
 
3161
                      "vneg", "f32", "$dst, $src", "", []>;
 
3162
def : N2VSPat<fneg, f32, v2f32, VNEGfd_sfp>;
 
3163
 
 
3164
// Vector Maximum used for single-precision FP
 
3165
let neverHasSideEffects = 1 in
 
3166
def VMAXfd_sfp : N3V<0, 0, 0b00, 0b1111, 0, 0, (outs DPR_VFP2:$dst),
 
3167
                     (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
 
3168
                     "vmax", "f32", "$dst, $src1, $src2", "", []>;
 
3169
def : N3VSPat<NEONfmax, VMAXfd_sfp>;
 
3170
 
 
3171
// Vector Minimum used for single-precision FP
 
3172
let neverHasSideEffects = 1 in
 
3173
def VMINfd_sfp : N3V<0, 0, 0b00, 0b1111, 0, 0, (outs DPR_VFP2:$dst),
 
3174
                     (ins DPR_VFP2:$src1, DPR_VFP2:$src2), IIC_VBIND,
 
3175
                     "vmin", "f32", "$dst, $src1, $src2", "", []>;
 
3176
def : N3VSPat<NEONfmin, VMINfd_sfp>;
 
3177
 
 
3178
// Vector Convert between single-precision FP and integer
 
3179
let neverHasSideEffects = 1 in
 
3180
def  VCVTf2sd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32",
 
3181
                         v2i32, v2f32, fp_to_sint>;
 
3182
def : N2VSPat<arm_ftosi, f32, v2f32, VCVTf2sd_sfp>;
 
3183
 
 
3184
let neverHasSideEffects = 1 in
 
3185
def  VCVTf2ud_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32",
 
3186
                         v2i32, v2f32, fp_to_uint>;
 
3187
def : N2VSPat<arm_ftoui, f32, v2f32, VCVTf2ud_sfp>;
 
3188
 
 
3189
let neverHasSideEffects = 1 in
 
3190
def  VCVTs2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32",
 
3191
                         v2f32, v2i32, sint_to_fp>;
 
3192
def : N2VSPat<arm_sitof, f32, v2i32, VCVTs2fd_sfp>;
 
3193
 
 
3194
let neverHasSideEffects = 1 in
 
3195
def  VCVTu2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32",
 
3196
                         v2f32, v2i32, uint_to_fp>;
 
3197
def : N2VSPat<arm_uitof, f32, v2i32, VCVTu2fd_sfp>;
 
3198
 
 
3199
//===----------------------------------------------------------------------===//
 
3200
// Non-Instruction Patterns
 
3201
//===----------------------------------------------------------------------===//
 
3202
 
 
3203
// bit_convert
 
3204
def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>;
 
3205
def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>;
 
3206
def : Pat<(v1i64 (bitconvert (v8i8  DPR:$src))), (v1i64 DPR:$src)>;
 
3207
def : Pat<(v1i64 (bitconvert (f64   DPR:$src))), (v1i64 DPR:$src)>;
 
3208
def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>;
 
3209
def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>;
 
3210
def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>;
 
3211
def : Pat<(v2i32 (bitconvert (v8i8  DPR:$src))), (v2i32 DPR:$src)>;
 
3212
def : Pat<(v2i32 (bitconvert (f64   DPR:$src))), (v2i32 DPR:$src)>;
 
3213
def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>;
 
3214
def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>;
 
3215
def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>;
 
3216
def : Pat<(v4i16 (bitconvert (v8i8  DPR:$src))), (v4i16 DPR:$src)>;
 
3217
def : Pat<(v4i16 (bitconvert (f64   DPR:$src))), (v4i16 DPR:$src)>;
 
3218
def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>;
 
3219
def : Pat<(v8i8  (bitconvert (v1i64 DPR:$src))), (v8i8  DPR:$src)>;
 
3220
def : Pat<(v8i8  (bitconvert (v2i32 DPR:$src))), (v8i8  DPR:$src)>;
 
3221
def : Pat<(v8i8  (bitconvert (v4i16 DPR:$src))), (v8i8  DPR:$src)>;
 
3222
def : Pat<(v8i8  (bitconvert (f64   DPR:$src))), (v8i8  DPR:$src)>;
 
3223
def : Pat<(v8i8  (bitconvert (v2f32 DPR:$src))), (v8i8  DPR:$src)>;
 
3224
def : Pat<(f64   (bitconvert (v1i64 DPR:$src))), (f64   DPR:$src)>;
 
3225
def : Pat<(f64   (bitconvert (v2i32 DPR:$src))), (f64   DPR:$src)>;
 
3226
def : Pat<(f64   (bitconvert (v4i16 DPR:$src))), (f64   DPR:$src)>;
 
3227
def : Pat<(f64   (bitconvert (v8i8  DPR:$src))), (f64   DPR:$src)>;
 
3228
def : Pat<(f64   (bitconvert (v2f32 DPR:$src))), (f64   DPR:$src)>;
 
3229
def : Pat<(v2f32 (bitconvert (f64   DPR:$src))), (v2f32 DPR:$src)>;
 
3230
def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>;
 
3231
def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>;
 
3232
def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>;
 
3233
def : Pat<(v2f32 (bitconvert (v8i8  DPR:$src))), (v2f32 DPR:$src)>;
 
3234
 
 
3235
def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>;
 
3236
def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>;
 
3237
def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>;
 
3238
def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>;
 
3239
def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>;
 
3240
def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>;
 
3241
def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>;
 
3242
def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>;
 
3243
def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>;
 
3244
def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>;
 
3245
def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>;
 
3246
def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>;
 
3247
def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>;
 
3248
def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>;
 
3249
def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>;
 
3250
def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>;
 
3251
def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>;
 
3252
def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>;
 
3253
def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>;
 
3254
def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>;
 
3255
def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>;
 
3256
def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>;
 
3257
def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>;
 
3258
def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>;
 
3259
def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>;
 
3260
def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>;
 
3261
def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>;
 
3262
def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>;
 
3263
def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>;
 
3264
def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>;