blob: 71ff34b02b1c36cceb151462a02bc9fd0de4c594 [file] [log] [blame]
Scott Michel8b6b4202007-12-04 22:35:58 +00001//==- SPUInstrInfo.td - Describe the Cell SPU Instructions -*- tablegen -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by The Aerospace Corporation.
6//
7//===----------------------------------------------------------------------===//
8// Cell SPU Instructions:
9//===----------------------------------------------------------------------===//
10
11//===----------------------------------------------------------------------===//
12// TODO Items (not urgent today, but would be nice, low priority)
13//
14// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by
15// concatenating the byte argument b as "bbbb". Could recognize this bit pattern
16// in 16-bit and 32-bit constants and reduce instruction count.
17//===----------------------------------------------------------------------===//
18
19//===----------------------------------------------------------------------===//
20// Pseudo instructions:
21//===----------------------------------------------------------------------===//
22
23let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in {
24 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt),
25 "${:comment} ADJCALLSTACKDOWN",
26 [(callseq_start imm:$amt)]>;
27 def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt),
28 "${:comment} ADJCALLSTACKUP",
29 [(callseq_end imm:$amt)]>;
30}
31
32//===----------------------------------------------------------------------===//
33// DWARF debugging Pseudo Instructions
34//===----------------------------------------------------------------------===//
35
36def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
37 "${:comment} .loc $file, $line, $col",
38 [(dwarf_loc (i32 imm:$line), (i32 imm:$col),
39 (i32 imm:$file))]>;
40
41//===----------------------------------------------------------------------===//
42// Loads:
43// NB: The ordering is actually important, since the instruction selection
44// will try each of the instructions in sequence, i.e., the D-form first with
45// the 10-bit displacement, then the A-form with the 16 bit displacement, and
46// finally the X-form with the register-register.
47//===----------------------------------------------------------------------===//
48
49let isLoad = 1 in {
50 def LQDv16i8:
51 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
52 "lqd\t$rT, $src", LoadStore,
53 [(set (v16i8 VECREG:$rT), (load dform_addr:$src))]>;
54
55 def LQDv8i16:
56 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
57 "lqd\t$rT, $src", LoadStore,
58 [(set (v8i16 VECREG:$rT), (load dform_addr:$src))]>;
59
60 def LQDv4i32:
61 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
62 "lqd\t$rT, $src", LoadStore,
63 [(set (v4i32 VECREG:$rT), (load dform_addr:$src))]>;
64
65 def LQDv2i64:
66 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
67 "lqd\t$rT, $src", LoadStore,
68 [(set (v2i64 VECREG:$rT), (load dform_addr:$src))]>;
69
70 def LQDv4f32:
71 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
72 "lqd\t$rT, $src", LoadStore,
73 [(set (v4f32 VECREG:$rT), (load dform_addr:$src))]>;
74
75 def LQDv2f64:
76 RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src),
77 "lqd\t$rT, $src", LoadStore,
78 [(set (v2f64 VECREG:$rT), (load dform_addr:$src))]>;
79
80 def LQDr128:
81 RI10Form<0b00101100, (outs GPRC:$rT), (ins memri10:$src),
82 "lqd\t$rT, $src", LoadStore,
83 [(set GPRC:$rT, (load dform_addr:$src))]>;
84
85 def LQDr64:
86 RI10Form<0b00101100, (outs R64C:$rT), (ins memri10:$src),
87 "lqd\t$rT, $src", LoadStore,
88 [(set R64C:$rT, (load dform_addr:$src))]>;
89
90 def LQDr32:
91 RI10Form<0b00101100, (outs R32C:$rT), (ins memri10:$src),
92 "lqd\t$rT, $src", LoadStore,
93 [(set R32C:$rT, (load dform_addr:$src))]>;
94
95 // Floating Point
96 def LQDf32:
97 RI10Form<0b00101100, (outs R32FP:$rT), (ins memri10:$src),
98 "lqd\t$rT, $src", LoadStore,
99 [(set R32FP:$rT, (load dform_addr:$src))]>;
100
101 def LQDf64:
102 RI10Form<0b00101100, (outs R64FP:$rT), (ins memri10:$src),
103 "lqd\t$rT, $src", LoadStore,
104 [(set R64FP:$rT, (load dform_addr:$src))]>;
105 // END Floating Point
106
107 def LQDr16:
108 RI10Form<0b00101100, (outs R16C:$rT), (ins memri10:$src),
109 "lqd\t$rT, $src", LoadStore,
110 [(set R16C:$rT, (load dform_addr:$src))]>;
111
112 def LQAv16i8:
113 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
114 "lqa\t$rT, $src", LoadStore,
115 [(set (v16i8 VECREG:$rT), (load aform_addr:$src))]>;
116
117 def LQAv8i16:
118 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
119 "lqa\t$rT, $src", LoadStore,
120 [(set (v8i16 VECREG:$rT), (load aform_addr:$src))]>;
121
122 def LQAv4i32:
123 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
124 "lqa\t$rT, $src", LoadStore,
125 [(set (v4i32 VECREG:$rT), (load aform_addr:$src))]>;
126
127 def LQAv2i64:
128 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
129 "lqa\t$rT, $src", LoadStore,
130 [(set (v2i64 VECREG:$rT), (load aform_addr:$src))]>;
131
132 def LQAv4f32:
133 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
134 "lqa\t$rT, $src", LoadStore,
135 [(set (v4f32 VECREG:$rT), (load aform_addr:$src))]>;
136
137 def LQAv2f64:
138 RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src),
139 "lqa\t$rT, $src", LoadStore,
140 [(set (v2f64 VECREG:$rT), (load aform_addr:$src))]>;
141
142 def LQAr128:
143 RI16Form<0b100001100, (outs GPRC:$rT), (ins addr256k:$src),
144 "lqa\t$rT, $src", LoadStore,
145 [(set GPRC:$rT, (load aform_addr:$src))]>;
146
147 def LQAr64:
148 RI16Form<0b100001100, (outs R64C:$rT), (ins addr256k:$src),
149 "lqa\t$rT, $src", LoadStore,
150 [(set R64C:$rT, (load aform_addr:$src))]>;
151
152 def LQAr32:
153 RI16Form<0b100001100, (outs R32C:$rT), (ins addr256k:$src),
154 "lqa\t$rT, $src", LoadStore,
155 [(set R32C:$rT, (load aform_addr:$src))]>;
156
157 def LQAf32:
158 RI16Form<0b100001100, (outs R32FP:$rT), (ins addr256k:$src),
159 "lqa\t$rT, $src", LoadStore,
160 [(set R32FP:$rT, (load aform_addr:$src))]>;
161
162 def LQAf64:
163 RI16Form<0b100001100, (outs R64FP:$rT), (ins addr256k:$src),
164 "lqa\t$rT, $src", LoadStore,
165 [(set R64FP:$rT, (load aform_addr:$src))]>;
166
167 def LQAr16:
168 RI16Form<0b100001100, (outs R16C:$rT), (ins addr256k:$src),
169 "lqa\t$rT, $src", LoadStore,
170 [(set R16C:$rT, (load aform_addr:$src))]>;
171
172 def LQXv16i8:
173 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
174 "lqx\t$rT, $src", LoadStore,
175 [(set (v16i8 VECREG:$rT), (load xform_addr:$src))]>;
176
177 def LQXv8i16:
178 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
179 "lqx\t$rT, $src", LoadStore,
180 [(set (v8i16 VECREG:$rT), (load xform_addr:$src))]>;
181
182 def LQXv4i32:
183 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
184 "lqx\t$rT, $src", LoadStore,
185 [(set (v4i32 VECREG:$rT), (load xform_addr:$src))]>;
186
187 def LQXv2i64:
188 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
189 "lqx\t$rT, $src", LoadStore,
190 [(set (v2i64 VECREG:$rT), (load xform_addr:$src))]>;
191
192 def LQXv4f32:
193 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
194 "lqx\t$rT, $src", LoadStore,
195 [(set (v4f32 VECREG:$rT), (load xform_addr:$src))]>;
196
197 def LQXv2f64:
198 RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src),
199 "lqx\t$rT, $src", LoadStore,
200 [(set (v2f64 VECREG:$rT), (load xform_addr:$src))]>;
201
202 def LQXr128:
203 RRForm<0b00100011100, (outs GPRC:$rT), (ins memrr:$src),
204 "lqx\t$rT, $src", LoadStore,
205 [(set GPRC:$rT, (load xform_addr:$src))]>;
206
207 def LQXr64:
208 RRForm<0b00100011100, (outs R64C:$rT), (ins memrr:$src),
209 "lqx\t$rT, $src", LoadStore,
210 [(set R64C:$rT, (load xform_addr:$src))]>;
211
212 def LQXr32:
213 RRForm<0b00100011100, (outs R32C:$rT), (ins memrr:$src),
214 "lqx\t$rT, $src", LoadStore,
215 [(set R32C:$rT, (load xform_addr:$src))]>;
216
217 def LQXf32:
218 RRForm<0b00100011100, (outs R32FP:$rT), (ins memrr:$src),
219 "lqx\t$rT, $src", LoadStore,
220 [(set R32FP:$rT, (load xform_addr:$src))]>;
221
222 def LQXf64:
223 RRForm<0b00100011100, (outs R64FP:$rT), (ins memrr:$src),
224 "lqx\t$rT, $src", LoadStore,
225 [(set R64FP:$rT, (load xform_addr:$src))]>;
226
227 def LQXr16:
228 RRForm<0b00100011100, (outs R16C:$rT), (ins memrr:$src),
229 "lqx\t$rT, $src", LoadStore,
230 [(set R16C:$rT, (load xform_addr:$src))]>;
231
232/* Load quadword, PC relative: Not much use at this point in time.
233 Might be of use later for relocatable code.
234 def LQR : RI16Form<0b111001100, (outs VECREG:$rT), (ins s16imm:$disp),
235 "lqr\t$rT, $disp", LoadStore,
236 [(set VECREG:$rT, (load iaddr:$disp))]>;
237 */
238
239 // Catch-all for unaligned loads:
240}
241
242//===----------------------------------------------------------------------===//
243// Stores:
244//===----------------------------------------------------------------------===//
245
246let isStore = 1 in {
247 def STQDv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
248 "stqd\t$rT, $src", LoadStore,
249 [(store (v16i8 VECREG:$rT), dform_addr:$src)]>;
250
251 def STQDv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
252 "stqd\t$rT, $src", LoadStore,
253 [(store (v8i16 VECREG:$rT), dform_addr:$src)]>;
254
255 def STQDv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
256 "stqd\t$rT, $src", LoadStore,
257 [(store (v4i32 VECREG:$rT), dform_addr:$src)]>;
258
259 def STQDv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
260 "stqd\t$rT, $src", LoadStore,
261 [(store (v2i64 VECREG:$rT), dform_addr:$src)]>;
262
263 def STQDv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
264 "stqd\t$rT, $src", LoadStore,
265 [(store (v4f32 VECREG:$rT), dform_addr:$src)]>;
266
267 def STQDv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src),
268 "stqd\t$rT, $src", LoadStore,
269 [(store (v2f64 VECREG:$rT), dform_addr:$src)]>;
270
271 def STQDr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, memri10:$src),
272 "stqd\t$rT, $src", LoadStore,
273 [(store GPRC:$rT, dform_addr:$src)]>;
274
275 def STQDr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, memri10:$src),
276 "stqd\t$rT, $src", LoadStore,
277 [(store R64C:$rT, dform_addr:$src)]>;
278
279 def STQDr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, memri10:$src),
280 "stqd\t$rT, $src", LoadStore,
281 [(store R32C:$rT, dform_addr:$src)]>;
282
283 // Floating Point
284 def STQDf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, memri10:$src),
285 "stqd\t$rT, $src", LoadStore,
286 [(store R32FP:$rT, dform_addr:$src)]>;
287
288 def STQDf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, memri10:$src),
289 "stqd\t$rT, $src", LoadStore,
290 [(store R64FP:$rT, dform_addr:$src)]>;
291
292 def STQDr16 : RI10Form<0b00100100, (outs), (ins R16C:$rT, memri10:$src),
293 "stqd\t$rT, $src", LoadStore,
294 [(store R16C:$rT, dform_addr:$src)]>;
295
296 def STQAv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
297 "stqa\t$rT, $src", LoadStore,
298 [(store (v16i8 VECREG:$rT), aform_addr:$src)]>;
299
300 def STQAv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
301 "stqa\t$rT, $src", LoadStore,
302 [(store (v8i16 VECREG:$rT), aform_addr:$src)]>;
303
304 def STQAv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
305 "stqa\t$rT, $src", LoadStore,
306 [(store (v4i32 VECREG:$rT), aform_addr:$src)]>;
307
308 def STQAv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
309 "stqa\t$rT, $src", LoadStore,
310 [(store (v2i64 VECREG:$rT), aform_addr:$src)]>;
311
312 def STQAv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
313 "stqa\t$rT, $src", LoadStore,
314 [(store (v4f32 VECREG:$rT), aform_addr:$src)]>;
315
316 def STQAv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src),
317 "stqa\t$rT, $src", LoadStore,
318 [(store (v2f64 VECREG:$rT), aform_addr:$src)]>;
319
320 def STQAr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, addr256k:$src),
321 "stqa\t$rT, $src", LoadStore,
322 [(store GPRC:$rT, aform_addr:$src)]>;
323
324 def STQAr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, addr256k:$src),
325 "stqa\t$rT, $src", LoadStore,
326 [(store R64C:$rT, aform_addr:$src)]>;
327
328 def STQAr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, addr256k:$src),
329 "stqa\t$rT, $src", LoadStore,
330 [(store R32C:$rT, aform_addr:$src)]>;
331
332 // Floating Point
333 def STQAf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, addr256k:$src),
334 "stqa\t$rT, $src", LoadStore,
335 [(store R32FP:$rT, aform_addr:$src)]>;
336
337 def STQAf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, addr256k:$src),
338 "stqa\t$rT, $src", LoadStore,
339 [(store R64FP:$rT, aform_addr:$src)]>;
340
341 def STQXv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
342 "stqx\t$rT, $src", LoadStore,
343 [(store (v16i8 VECREG:$rT), xform_addr:$src)]>;
344
345 def STQXv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
346 "stqx\t$rT, $src", LoadStore,
347 [(store (v8i16 VECREG:$rT), xform_addr:$src)]>;
348
349 def STQXv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
350 "stqx\t$rT, $src", LoadStore,
351 [(store (v4i32 VECREG:$rT), xform_addr:$src)]>;
352
353 def STQXv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
354 "stqx\t$rT, $src", LoadStore,
355 [(store (v2i64 VECREG:$rT), xform_addr:$src)]>;
356
357 def STQXv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
358 "stqx\t$rT, $src", LoadStore,
359 [(store (v4f32 VECREG:$rT), xform_addr:$src)]>;
360
361 def STQXv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src),
362 "stqx\t$rT, $src", LoadStore,
363 [(store (v2f64 VECREG:$rT), xform_addr:$src)]>;
364
365 def STQXr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, memrr:$src),
366 "stqx\t$rT, $src", LoadStore,
367 [(store GPRC:$rT, xform_addr:$src)]>;
368
369 def STQXr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, memrr:$src),
370 "stqx\t$rT, $src", LoadStore,
371 [(store R64C:$rT, xform_addr:$src)]>;
372
373 def STQXr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, memrr:$src),
374 "stqx\t$rT, $src", LoadStore,
375 [(store R32C:$rT, xform_addr:$src)]>;
376
377 // Floating Point
378 def STQXf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, memrr:$src),
379 "stqx\t$rT, $src", LoadStore,
380 [(store R32FP:$rT, xform_addr:$src)]>;
381
382 def STQXf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, memrr:$src),
383 "stqx\t$rT, $src", LoadStore,
384 [(store R64FP:$rT, xform_addr:$src)]>;
385
386 def STQXr16 : RI10Form<0b00100100, (outs), (ins R16C:$rT, memrr:$src),
387 "stqx\t$rT, $src", LoadStore,
388 [(store R16C:$rT, xform_addr:$src)]>;
389
390/* Store quadword, PC relative: Not much use at this point in time. Might
391 be useful for relocatable code.
392 def STQR : RI16Form<0b111000100, (outs), (ins VECREG:$rT, s16imm:$disp),
393 "stqr\t$rT, $disp", LoadStore,
394 [(store VECREG:$rT, iaddr:$disp)]>;
395 */
396}
397
398//===----------------------------------------------------------------------===//
399// Generate Controls for Insertion:
400//===----------------------------------------------------------------------===//
401
402def CBD :
403 RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src),
404 "cbd\t$rT, $src", ShuffleOp,
405 [(set (v16i8 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>;
406
407def CBX : RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src),
408 "cbx\t$rT, $src", ShuffleOp,
409 [(set (v16i8 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>;
410
411def CHD : RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src),
412 "chd\t$rT, $src", ShuffleOp,
413 [(set (v8i16 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>;
414
415def CHX : RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src),
416 "chx\t$rT, $src", ShuffleOp,
417 [(set (v8i16 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>;
418
419def CWD : RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src),
420 "cwd\t$rT, $src", ShuffleOp,
421 [(set (v4i32 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>;
422
423def CWX : RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src),
424 "cwx\t$rT, $src", ShuffleOp,
425 [(set (v4i32 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>;
426
427def CDD : RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src),
428 "cdd\t$rT, $src", ShuffleOp,
429 [(set (v2i64 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>;
430
431def CDX : RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src),
432 "cdx\t$rT, $src", ShuffleOp,
433 [(set (v2i64 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>;
434
435//===----------------------------------------------------------------------===//
436// Constant formation:
437//===----------------------------------------------------------------------===//
438
439def ILHv8i16:
440 RI16Form<0b110000010, (outs VECREG:$rT), (ins s16imm:$val),
441 "ilh\t$rT, $val", ImmLoad,
442 [(set (v8i16 VECREG:$rT), (v8i16 v8i16SExt16Imm:$val))]>;
443
444def ILHr16:
445 RI16Form<0b110000010, (outs R16C:$rT), (ins s16imm:$val),
446 "ilh\t$rT, $val", ImmLoad,
447 [(set R16C:$rT, immSExt16:$val)]>;
448
449// IL does sign extension!
450def ILr64:
451 RI16Form<0b100000010, (outs R64C:$rT), (ins s16imm_i64:$val),
452 "il\t$rT, $val", ImmLoad,
453 [(set R64C:$rT, immSExt16:$val)]>;
454
455def ILv2i64:
456 RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm_i64:$val),
457 "il\t$rT, $val", ImmLoad,
458 [(set VECREG:$rT, (v2i64 v2i64SExt16Imm:$val))]>;
459
460def ILv4i32:
461 RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm:$val),
462 "il\t$rT, $val", ImmLoad,
463 [(set VECREG:$rT, (v4i32 v4i32SExt16Imm:$val))]>;
464
465def ILr32:
466 RI16Form<0b100000010, (outs R32C:$rT), (ins s16imm_i32:$val),
467 "il\t$rT, $val", ImmLoad,
468 [(set R32C:$rT, immSExt16:$val)]>;
469
470def ILf32:
471 RI16Form<0b100000010, (outs R32FP:$rT), (ins s16imm_f32:$val),
472 "il\t$rT, $val", ImmLoad,
473 [(set R32FP:$rT, (SPUFPconstant fpimmSExt16:$val))]>;
474
475def ILf64:
476 RI16Form<0b100000010, (outs R64FP:$rT), (ins s16imm_f64:$val),
477 "il\t$rT, $val", ImmLoad,
478 [(set R64FP:$rT, (SPUFPconstant fpimmSExt16:$val))]>;
479
480def ILHUv4i32:
481 RI16Form<0b010000010, (outs VECREG:$rT), (ins u16imm:$val),
482 "ilhu\t$rT, $val", ImmLoad,
483 [(set VECREG:$rT, (v4i32 immILHUvec:$val))]>;
484
485def ILHUr32:
486 RI16Form<0b010000010, (outs R32C:$rT), (ins u16imm:$val),
487 "ilhu\t$rT, $val", ImmLoad,
488 [(set R32C:$rT, hi16:$val)]>;
489
490// ILHUf32: Used to custom lower float constant loads
491def ILHUf32:
492 RI16Form<0b010000010, (outs R32FP:$rT), (ins f16imm:$val),
493 "ilhu\t$rT, $val", ImmLoad,
494 [(set R32FP:$rT, (SPUFPconstant hi16_f32:$val))]>;
495
496// ILHUhi: Used for loading high portion of an address. Note the symbolHi
497// printer used for the operand.
498def ILHUhi : RI16Form<0b010000010, (outs R32C:$rT), (ins symbolHi:$val),
499 "ilhu\t$rT, $val", ImmLoad,
500 [(set R32C:$rT, hi16:$val)]>;
501
502// Immediate load address (can also be used to load 18-bit unsigned constants,
503// see the zext 16->32 pattern)
504def ILAr64:
505 RI18Form<0b1000010, (outs R64C:$rT), (ins u18imm_i64:$val),
506 "ila\t$rT, $val", LoadNOP,
507 [(set R64C:$rT, imm18:$val)]>;
508
509// TODO: ILAv2i64
510
511def ILAv2i64:
512 RI18Form<0b1000010, (outs VECREG:$rT), (ins u18imm:$val),
513 "ila\t$rT, $val", LoadNOP,
514 [(set (v2i64 VECREG:$rT), v2i64Uns18Imm:$val)]>;
515
516def ILAv4i32:
517 RI18Form<0b1000010, (outs VECREG:$rT), (ins u18imm:$val),
518 "ila\t$rT, $val", LoadNOP,
519 [(set (v4i32 VECREG:$rT), v4i32Uns18Imm:$val)]>;
520
521def ILAr32:
522 RI18Form<0b1000010, (outs R32C:$rT), (ins u18imm:$val),
523 "ila\t$rT, $val", LoadNOP,
524 [(set R32C:$rT, imm18:$val)]>;
525
526def ILAf32:
527 RI18Form<0b1000010, (outs R32FP:$rT), (ins f18imm:$val),
528 "ila\t$rT, $val", LoadNOP,
529 [(set R32FP:$rT, (SPUFPconstant fpimm18:$val))]>;
530
531def ILAf64:
532 RI18Form<0b1000010, (outs R64FP:$rT), (ins f18imm_f64:$val),
533 "ila\t$rT, $val", LoadNOP,
534 [(set R64FP:$rT, (SPUFPconstant fpimm18:$val))]>;
535
536def ILAlo:
537 RI18Form<0b1000010, (outs R32C:$rT), (ins symbolLo:$val),
538 "ila\t$rT, $val", ImmLoad,
539 [(set R32C:$rT, imm18:$val)]>;
540
541def ILAlsa:
542 RI18Form<0b1000010, (outs R32C:$rT), (ins symbolLSA:$val),
543 "ila\t$rT, $val", ImmLoad,
544 [/* no pattern */]>;
545
546// Immediate OR, Halfword Lower: The "other" part of loading large constants
547// into 32-bit registers. See the anonymous pattern Pat<(i32 imm:$imm), ...>
548// Note that these are really two operand instructions, but they're encoded
549// as three operands with the first two arguments tied-to each other.
550
551def IOHLvec:
552 RI16Form<0b100000110, (outs VECREG:$rT), (ins VECREG:$rS, u16imm:$val),
553 "iohl\t$rT, $val", ImmLoad,
554 [/* insert intrinsic here */]>,
555 RegConstraint<"$rS = $rT">,
556 NoEncode<"$rS">;
557
558def IOHLr32:
559 RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, i32imm:$val),
560 "iohl\t$rT, $val", ImmLoad,
561 [/* insert intrinsic here */]>,
562 RegConstraint<"$rS = $rT">,
563 NoEncode<"$rS">;
564
565def IOHLf32:
566 RI16Form<0b100000110, (outs R32FP:$rT), (ins R32FP:$rS, f32imm:$val),
567 "iohl\t$rT, $val", ImmLoad,
568 [/* insert intrinsic here */]>,
569 RegConstraint<"$rS = $rT">,
570 NoEncode<"$rS">;
571
572// Form select mask for bytes using immediate, used in conjunction with the
573// SELB instruction:
574
575def FSMBIv16i8 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val),
576 "fsmbi\t$rT, $val", SelectOp,
577 [(set (v16i8 VECREG:$rT), (SPUfsmbi_v16i8 immU16:$val))]>;
578
579def FSMBIv8i16 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val),
580 "fsmbi\t$rT, $val", SelectOp,
581 [(set (v8i16 VECREG:$rT), (SPUfsmbi_v8i16 immU16:$val))]>;
582
583def FSMBIvecv4i32 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val),
584 "fsmbi\t$rT, $val", SelectOp,
585 [(set (v4i32 VECREG:$rT), (SPUfsmbi_v4i32 immU16:$val))]>;
586
587//===----------------------------------------------------------------------===//
588// Integer and Logical Operations:
589//===----------------------------------------------------------------------===//
590
591def AHv8i16:
592 RRForm<0b00010011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
593 "ah\t$rT, $rA, $rB", IntegerOp,
594 [(set (v8i16 VECREG:$rT), (int_spu_si_ah VECREG:$rA, VECREG:$rB))]>;
595
596def : Pat<(add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)),
597 (AHv8i16 VECREG:$rA, VECREG:$rB)>;
598
599// [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
600
601def AHr16:
602 RRForm<0b00010011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
603 "ah\t$rT, $rA, $rB", IntegerOp,
604 [(set R16C:$rT, (add R16C:$rA, R16C:$rB))]>;
605
606def AHIvec:
607 RI10Form<0b10111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
608 "ahi\t$rT, $rA, $val", IntegerOp,
609 [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA),
610 v8i16SExt10Imm:$val))]>;
611
612def AHIr16 : RI10Form<0b10111000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
613 "ahi\t$rT, $rA, $val", IntegerOp,
614 [(set R16C:$rT, (add R16C:$rA, v8i16SExt10Imm:$val))]>;
615
616def Avec : RRForm<0b00000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
617 "a\t$rT, $rA, $rB", IntegerOp,
618 [(set (v4i32 VECREG:$rT), (add (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
619
620def : Pat<(add (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)),
621 (Avec VECREG:$rA, VECREG:$rB)>;
622
623def Ar32 : RRForm<0b00000011000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
624 "a\t$rT, $rA, $rB", IntegerOp,
625 [(set R32C:$rT, (add R32C:$rA, R32C:$rB))]>;
626
627def AIvec:
628 RI10Form<0b00111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
629 "ai\t$rT, $rA, $val", IntegerOp,
630 [(set (v4i32 VECREG:$rT), (add (v4i32 VECREG:$rA),
631 v4i32SExt10Imm:$val))]>;
632
633def AIr32 : RI10Form<0b00111000, (outs R32C:$rT),
634 (ins R32C:$rA, s10imm_i32:$val),
635 "ai\t$rT, $rA, $val", IntegerOp,
636 [(set R32C:$rT, (add R32C:$rA, i32ImmSExt10:$val))]>;
637
638def SFHvec : RRForm<0b00010010000, (outs VECREG:$rT),
639 (ins VECREG:$rA, VECREG:$rB),
640 "sfh\t$rT, $rA, $rB", IntegerOp,
641 [(set (v8i16 VECREG:$rT), (sub (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
642
643def SFHr16 : RRForm<0b00010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
644 "sfh\t$rT, $rA, $rB", IntegerOp,
645 [(set R16C:$rT, (sub R16C:$rA, R16C:$rB))]>;
646
647def SFHIvec:
648 RI10Form<0b10110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
649 "sfhi\t$rT, $rA, $val", IntegerOp,
650 [(set (v8i16 VECREG:$rT), (sub v8i16SExt10Imm:$val,
651 (v8i16 VECREG:$rA)))]>;
652
653def SFHIr16 : RI10Form<0b10110000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
654 "sfhi\t$rT, $rA, $val", IntegerOp,
655 [(set R16C:$rT, (sub i16ImmSExt10:$val, R16C:$rA))]>;
656
657def SFvec : RRForm<0b00000010000, (outs VECREG:$rT),
658 (ins VECREG:$rA, VECREG:$rB),
659 "sf\t$rT, $rA, $rB", IntegerOp,
660 [(set (v4i32 VECREG:$rT), (sub (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
661
662def SFr32 : RRForm<0b00000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
663 "sf\t$rT, $rA, $rB", IntegerOp,
664 [(set R32C:$rT, (sub R32C:$rA, R32C:$rB))]>;
665
666def SFIvec:
667 RI10Form<0b00110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
668 "sfi\t$rT, $rA, $val", IntegerOp,
669 [(set (v4i32 VECREG:$rT), (sub v4i32SExt10Imm:$val,
670 (v4i32 VECREG:$rA)))]>;
671
672def SFIr32 : RI10Form<0b00110000, (outs R32C:$rT),
673 (ins R32C:$rA, s10imm_i32:$val),
674 "sfi\t$rT, $rA, $val", IntegerOp,
675 [(set R32C:$rT, (sub i32ImmSExt10:$val, R32C:$rA))]>;
676
677// ADDX: only available in vector form, doesn't match a pattern.
678def ADDXvec:
679 RRForm<0b00000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB,
680 VECREG:$rCarry),
681 "addx\t$rT, $rA, $rB", IntegerOp,
682 []>,
683 RegConstraint<"$rCarry = $rT">,
684 NoEncode<"$rCarry">;
685
686// CG: only available in vector form, doesn't match a pattern.
687def CGvec:
688 RRForm<0b01000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB,
689 VECREG:$rCarry),
690 "cg\t$rT, $rA, $rB", IntegerOp,
691 []>,
692 RegConstraint<"$rCarry = $rT">,
693 NoEncode<"$rCarry">;
694
695// SFX: only available in vector form, doesn't match a pattern
696def SFXvec:
697 RRForm<0b10000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB,
698 VECREG:$rCarry),
699 "sfx\t$rT, $rA, $rB", IntegerOp,
700 []>,
701 RegConstraint<"$rCarry = $rT">,
702 NoEncode<"$rCarry">;
703
704// BG: only available in vector form, doesn't match a pattern.
705def BGvec:
706 RRForm<0b01000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB,
707 VECREG:$rCarry),
708 "bg\t$rT, $rA, $rB", IntegerOp,
709 []>,
710 RegConstraint<"$rCarry = $rT">,
711 NoEncode<"$rCarry">;
712
713// BGX: only available in vector form, doesn't match a pattern.
714def BGXvec:
715 RRForm<0b11000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB,
716 VECREG:$rCarry),
717 "bgx\t$rT, $rA, $rB", IntegerOp,
718 []>,
719 RegConstraint<"$rCarry = $rT">,
720 NoEncode<"$rCarry">;
721
722// Halfword multiply variants:
723// N.B: These can be used to build up larger quantities (16x16 -> 32)
724
725def MPYv8i16:
726 RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
727 "mpy\t$rT, $rA, $rB", IntegerMulDiv,
728 [(set (v8i16 VECREG:$rT), (SPUmpy_v8i16 (v8i16 VECREG:$rA),
729 (v8i16 VECREG:$rB)))]>;
730
731def MPYr16:
732 RRForm<0b00100011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
733 "mpy\t$rT, $rA, $rB", IntegerMulDiv,
734 [(set R16C:$rT, (mul R16C:$rA, R16C:$rB))]>;
735
736def MPYUv4i32:
737 RRForm<0b00110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
738 "mpyu\t$rT, $rA, $rB", IntegerMulDiv,
739 [(set (v4i32 VECREG:$rT),
740 (SPUmpyu_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
741
742def MPYUr16:
743 RRForm<0b00110011110, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB),
744 "mpyu\t$rT, $rA, $rB", IntegerMulDiv,
745 [(set R32C:$rT, (mul (zext R16C:$rA),
746 (zext R16C:$rB)))]>;
747
748def MPYUr32:
749 RRForm<0b00110011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
750 "mpyu\t$rT, $rA, $rB", IntegerMulDiv,
751 [(set R32C:$rT, (SPUmpyu_i32 R32C:$rA, R32C:$rB))]>;
752
753// mpyi: multiply 16 x s10imm -> 32 result (custom lowering for 32 bit result,
754// this only produces the lower 16 bits)
755def MPYIvec:
756 RI10Form<0b00101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
757 "mpyi\t$rT, $rA, $val", IntegerMulDiv,
758 [(set (v8i16 VECREG:$rT), (mul (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>;
759
760def MPYIr16:
761 RI10Form<0b00101110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
762 "mpyi\t$rT, $rA, $val", IntegerMulDiv,
763 [(set R16C:$rT, (mul R16C:$rA, i16ImmSExt10:$val))]>;
764
765// mpyui: same issues as other multiplies, plus, this doesn't match a
766// pattern... but may be used during target DAG selection or lowering
767def MPYUIvec:
768 RI10Form<0b10101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
769 "mpyui\t$rT, $rA, $val", IntegerMulDiv,
770 []>;
771
772def MPYUIr16:
773 RI10Form<0b10101110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
774 "mpyui\t$rT, $rA, $val", IntegerMulDiv,
775 []>;
776
777// mpya: 16 x 16 + 16 -> 32 bit result
778def MPYAvec:
779 RRRForm<0b0011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
780 "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv,
781 [(set (v4i32 VECREG:$rT), (add (v4i32 (bitconvert (mul (v8i16 VECREG:$rA),
782 (v8i16 VECREG:$rB)))),
783 (v4i32 VECREG:$rC)))]>;
784
785def MPYAr32:
786 RRRForm<0b0011, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC),
787 "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv,
788 [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)),
789 R32C:$rC))]>;
790
791def : Pat<(add (mul (sext R16C:$rA), (sext R16C:$rB)), R32C:$rC),
792 (MPYAr32 R16C:$rA, R16C:$rB, R32C:$rC)>;
793
794def MPYAr32_sextinreg:
795 RRRForm<0b0011, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC),
796 "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv,
797 [(set R32C:$rT, (add (mul (sext_inreg R32C:$rA, i16),
798 (sext_inreg R32C:$rB, i16)),
799 R32C:$rC))]>;
800
801//def MPYAr32:
802// RRRForm<0b0011, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC),
803// "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv,
804// [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)),
805// R32C:$rC))]>;
806
807// mpyh: multiply high, used to synthesize 32-bit multiplies
808def MPYHv4i32:
809 RRForm<0b10100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
810 "mpyh\t$rT, $rA, $rB", IntegerMulDiv,
811 [(set (v4i32 VECREG:$rT),
812 (SPUmpyh_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
813
814def MPYHr32:
815 RRForm<0b10100011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
816 "mpyh\t$rT, $rA, $rB", IntegerMulDiv,
817 [(set R32C:$rT, (SPUmpyh_i32 R32C:$rA, R32C:$rB))]>;
818
819// mpys: multiply high and shift right (returns the top half of
820// a 16-bit multiply, sign extended to 32 bits.)
821def MPYSvec:
822 RRForm<0b11100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
823 "mpys\t$rT, $rA, $rB", IntegerMulDiv,
824 []>;
825
826def MPYSr16:
827 RRForm<0b11100011110, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB),
828 "mpys\t$rT, $rA, $rB", IntegerMulDiv,
829 []>;
830
831// mpyhh: multiply high-high (returns the 32-bit result from multiplying
832// the top 16 bits of the $rA, $rB)
833def MPYHHv8i16:
834 RRForm<0b01100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
835 "mpyhh\t$rT, $rA, $rB", IntegerMulDiv,
836 [(set (v8i16 VECREG:$rT),
837 (SPUmpyhh_v8i16 (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
838
839def MPYHHr32:
840 RRForm<0b01100011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
841 "mpyhh\t$rT, $rA, $rB", IntegerMulDiv,
842 []>;
843
844// mpyhha: Multiply high-high, add to $rT:
845def MPYHHAvec:
846 RRForm<0b01100010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
847 "mpyhha\t$rT, $rA, $rB", IntegerMulDiv,
848 []>;
849
850def MPYHHAr32:
851 RRForm<0b01100010110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
852 "mpyhha\t$rT, $rA, $rB", IntegerMulDiv,
853 []>;
854
855// mpyhhu: Multiply high-high, unsigned
856def MPYHHUvec:
857 RRForm<0b01110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
858 "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv,
859 []>;
860
861def MPYHHUr32:
862 RRForm<0b01110011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
863 "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv,
864 []>;
865
866// mpyhhau: Multiply high-high, unsigned
867def MPYHHAUvec:
868 RRForm<0b01110010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
869 "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv,
870 []>;
871
872def MPYHHAUr32:
873 RRForm<0b01110010110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
874 "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv,
875 []>;
876
877// clz: Count leading zeroes
878def CLZv4i32:
879 RRForm_1<0b10100101010, (outs VECREG:$rT), (ins VECREG:$rA),
880 "clz\t$rT, $rA", IntegerOp,
881 [/* intrinsic */]>;
882
883def CLZr32:
884 RRForm_1<0b10100101010, (outs R32C:$rT), (ins R32C:$rA),
885 "clz\t$rT, $rA", IntegerOp,
886 [(set R32C:$rT, (ctlz R32C:$rA))]>;
887
888// cntb: Count ones in bytes (aka "population count")
889// NOTE: This instruction is really a vector instruction, but the custom
890// lowering code uses it in unorthodox ways to support CTPOP for other
891// data types!
892def CNTBv16i8:
893 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA),
894 "cntb\t$rT, $rA", IntegerOp,
895 [(set (v16i8 VECREG:$rT), (SPUcntb_v16i8 (v16i8 VECREG:$rA)))]>;
896
897def CNTBv8i16 :
898 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA),
899 "cntb\t$rT, $rA", IntegerOp,
900 [(set (v8i16 VECREG:$rT), (SPUcntb_v8i16 (v8i16 VECREG:$rA)))]>;
901
902def CNTBv4i32 :
903 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA),
904 "cntb\t$rT, $rA", IntegerOp,
905 [(set (v4i32 VECREG:$rT), (SPUcntb_v4i32 (v4i32 VECREG:$rA)))]>;
906
907// fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits
908def FSMB:
909 RRForm_1<0b01101101100, (outs VECREG:$rT), (ins R16C:$rA),
910 "fsmb\t$rT, $rA", SelectOp,
911 []>;
912
913// fsmh: Form select mask for halfwords. N.B., Input operand, $rA, is
914// only 8-bits wide (even though it's input as 16-bits here)
915def FSMH:
916 RRForm_1<0b10101101100, (outs VECREG:$rT), (ins R16C:$rA),
917 "fsmh\t$rT, $rA", SelectOp,
918 []>;
919
920// fsm: Form select mask for words. Like the other fsm* instructions,
921// only the lower 4 bits of $rA are significant.
922def FSM:
923 RRForm_1<0b00101101100, (outs VECREG:$rT), (ins R16C:$rA),
924 "fsm\t$rT, $rA", SelectOp,
925 []>;
926
927// gbb: Gather all low order bits from each byte in $rA into a single 16-bit
928// quantity stored into $rT
929def GBB:
930 RRForm_1<0b01001101100, (outs R16C:$rT), (ins VECREG:$rA),
931 "gbb\t$rT, $rA", GatherOp,
932 []>;
933
934// gbh: Gather all low order bits from each halfword in $rA into a single
935// 8-bit quantity stored in $rT
936def GBH:
937 RRForm_1<0b10001101100, (outs R16C:$rT), (ins VECREG:$rA),
938 "gbh\t$rT, $rA", GatherOp,
939 []>;
940
941// gb: Gather all low order bits from each word in $rA into a single
942// 4-bit quantity stored in $rT
943def GB:
944 RRForm_1<0b00001101100, (outs R16C:$rT), (ins VECREG:$rA),
945 "gb\t$rT, $rA", GatherOp,
946 []>;
947
948// avgb: average bytes
949def AVGB:
950 RRForm<0b11001011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
951 "avgb\t$rT, $rA, $rB", ByteOp,
952 []>;
953
954// absdb: absolute difference of bytes
955def ABSDB:
956 RRForm<0b11001010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
957 "absdb\t$rT, $rA, $rB", ByteOp,
958 []>;
959
960// sumb: sum bytes into halfwords
961def SUMB:
962 RRForm<0b11001010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
963 "sumb\t$rT, $rA, $rB", ByteOp,
964 []>;
965
966// Sign extension operations:
967def XSBHvec:
968 RRForm_1<0b01101101010, (outs VECREG:$rDst), (ins VECREG:$rSrc),
969 "xsbh\t$rDst, $rSrc", IntegerOp,
970 [(set (v8i16 VECREG:$rDst), (sext (v16i8 VECREG:$rSrc)))]>;
971
972// Ordinary form for XSBH
973def XSBHr16:
974 RRForm_1<0b01101101010, (outs R16C:$rDst), (ins R16C:$rSrc),
975 "xsbh\t$rDst, $rSrc", IntegerOp,
976 [(set R16C:$rDst, (sext_inreg R16C:$rSrc, i8))]>;
977
978// 32-bit form for XSBH: used to sign extend 8-bit quantities to 16-bit
979// quantities to 32-bit quantities via a 32-bit register (see the sext 8->32
980// pattern below). Intentionally doesn't match a pattern because we want the
981// sext 8->32 pattern to do the work for us, namely because we need the extra
982// XSHWr32.
983def XSBHr32:
984 RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R32C:$rSrc),
985 "xsbh\t$rDst, $rSrc", IntegerOp,
986 [(set R32C:$rDst, (sext_inreg R32C:$rSrc, i8))]>;
987
988// Sign extend halfwords to words:
989def XSHWvec:
990 RRForm_1<0b01101101010, (outs VECREG:$rDest), (ins VECREG:$rSrc),
991 "xshw\t$rDest, $rSrc", IntegerOp,
992 [(set (v4i32 VECREG:$rDest), (sext (v8i16 VECREG:$rSrc)))]>;
993
994def XSHWr32:
995 RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R32C:$rSrc),
996 "xshw\t$rDst, $rSrc", IntegerOp,
997 [(set R32C:$rDst, (sext_inreg R32C:$rSrc, i16))]>;
998
999def XSHWr16:
1000 RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R16C:$rSrc),
1001 "xshw\t$rDst, $rSrc", IntegerOp,
1002 [(set R32C:$rDst, (sext R16C:$rSrc))]>;
1003
1004def XSWDvec:
1005 RRForm_1<0b01100101010, (outs VECREG:$rDst), (ins VECREG:$rSrc),
1006 "xswd\t$rDst, $rSrc", IntegerOp,
1007 [(set (v2i64 VECREG:$rDst), (sext (v4i32 VECREG:$rSrc)))]>;
1008
1009def XSWDr64:
1010 RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R64C:$rSrc),
1011 "xswd\t$rDst, $rSrc", IntegerOp,
1012 [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>;
1013
1014def XSWDr32:
1015 RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R32C:$rSrc),
1016 "xswd\t$rDst, $rSrc", IntegerOp,
1017 [(set R64C:$rDst, (SPUsext32_to_64 R32C:$rSrc))]>;
1018
1019def : Pat<(sext R32C:$inp),
1020 (XSWDr32 R32C:$inp)>;
1021
1022// AND operations
1023def ANDv16i8:
1024 RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1025 "and\t$rT, $rA, $rB", IntegerOp,
1026 [(set (v16i8 VECREG:$rT), (and (v16i8 VECREG:$rA),
1027 (v16i8 VECREG:$rB)))]>;
1028
1029def ANDv8i16:
1030 RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1031 "and\t$rT, $rA, $rB", IntegerOp,
1032 [(set (v8i16 VECREG:$rT), (and (v8i16 VECREG:$rA),
1033 (v8i16 VECREG:$rB)))]>;
1034
1035def ANDv4i32:
1036 RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1037 "and\t$rT, $rA, $rB", IntegerOp,
1038 [(set (v4i32 VECREG:$rT), (and (v4i32 VECREG:$rA),
1039 (v4i32 VECREG:$rB)))]>;
1040
1041def ANDr32:
1042 RRForm<0b10000011000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1043 "and\t$rT, $rA, $rB", IntegerOp,
1044 [(set R32C:$rT, (and R32C:$rA, R32C:$rB))]>;
1045
1046//===---------------------------------------------
1047// Special instructions to perform the fabs instruction
1048def ANDfabs32:
1049 RRForm<0b10000011000, (outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
1050 "and\t$rT, $rA, $rB", IntegerOp,
1051 [/* Intentionally does not match a pattern */]>;
1052
1053def ANDfabs64:
1054 RRForm<0b10000011000, (outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
1055 "and\t$rT, $rA, $rB", IntegerOp,
1056 [/* Intentionally does not match a pattern */]>;
1057
1058// Could use ANDv4i32, but won't for clarity
1059def ANDfabsvec:
1060 RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1061 "and\t$rT, $rA, $rB", IntegerOp,
1062 [/* Intentionally does not match a pattern */]>;
1063
1064//===---------------------------------------------
1065
1066def ANDr16:
1067 RRForm<0b10000011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1068 "and\t$rT, $rA, $rB", IntegerOp,
1069 [(set R16C:$rT, (and R16C:$rA, R16C:$rB))]>;
1070
1071// Hacked form of AND to zero-extend 16-bit quantities to 32-bit
1072// quantities -- see 16->32 zext pattern.
1073//
1074// This pattern is somewhat artificial, since it might match some
1075// compiler generated pattern but it is unlikely to do so.
1076def AND2To4:
1077 RRForm<0b10000011000, (outs R32C:$rT), (ins R16C:$rA, R32C:$rB),
1078 "and\t$rT, $rA, $rB", IntegerOp,
1079 [(set R32C:$rT, (and (zext R16C:$rA), R32C:$rB))]>;
1080
1081// N.B.: vnot_conv is one of those special target selection pattern fragments,
1082// in which we expect there to be a bit_convert on the constant. Bear in mind
1083// that llvm translates "not <reg>" to "xor <reg>, -1" (or in this case, a
1084// constant -1 vector.)
1085def ANDCv16i8:
1086 RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1087 "andc\t$rT, $rA, $rB", IntegerOp,
1088 [(set (v16i8 VECREG:$rT), (and (v16i8 VECREG:$rA),
1089 (vnot (v16i8 VECREG:$rB))))]>;
1090
1091def ANDCv8i16:
1092 RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1093 "andc\t$rT, $rA, $rB", IntegerOp,
1094 [(set (v8i16 VECREG:$rT), (and (v8i16 VECREG:$rA),
1095 (vnot (v8i16 VECREG:$rB))))]>;
1096
1097def ANDCv4i32:
1098 RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1099 "andc\t$rT, $rA, $rB", IntegerOp,
1100 [(set (v4i32 VECREG:$rT), (and (v4i32 VECREG:$rA),
1101 (vnot (v4i32 VECREG:$rB))))]>;
1102
1103def ANDCr32:
1104 RRForm<0b10000011010, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1105 "andc\t$rT, $rA, $rB", IntegerOp,
1106 [(set R32C:$rT, (and R32C:$rA, (not R32C:$rB)))]>;
1107
1108def ANDCr16:
1109 RRForm<0b10000011010, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1110 "andc\t$rT, $rA, $rB", IntegerOp,
1111 [(set R16C:$rT, (and R16C:$rA, (not R16C:$rB)))]>;
1112
1113def ANDBIv16i8:
1114 RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
1115 "andbi\t$rT, $rA, $val", IntegerOp,
1116 [(set (v16i8 VECREG:$rT),
1117 (and (v16i8 VECREG:$rA), (v16i8 v16i8U8Imm:$val)))]>;
1118
1119def ANDHIv8i16:
1120 RI10Form<0b10101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1121 "andhi\t$rT, $rA, $val", IntegerOp,
1122 [(set (v8i16 VECREG:$rT),
1123 (and (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>;
1124
1125def ANDHIr16:
1126 RI10Form<0b10101000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
1127 "andhi\t$rT, $rA, $val", IntegerOp,
1128 [(set R16C:$rT, (and R16C:$rA, i16ImmSExt10:$val))]>;
1129
1130def ANDIv4i32:
1131 RI10Form<0b00101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1132 "andi\t$rT, $rA, $val", IntegerOp,
1133 [(set (v4i32 VECREG:$rT),
1134 (and (v4i32 VECREG:$rA), v4i32SExt10Imm:$val))]>;
1135
1136def ANDIr32:
1137 RI10Form<0b10101000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val),
1138 "andi\t$rT, $rA, $val", IntegerOp,
1139 [(set R32C:$rT, (and R32C:$rA, i32ImmSExt10:$val))]>;
1140
1141// Hacked form of ANDI to zero-extend i16 quantities to i32. See the
1142// zext 16->32 pattern below.
1143//
1144// Note that this pattern is somewhat artificial, since it might match
1145// something the compiler generates but is unlikely to occur in practice.
1146def ANDI2To4:
1147 RI10Form<0b10101000, (outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val),
1148 "andi\t$rT, $rA, $val", IntegerOp,
1149 [(set R32C:$rT, (and (zext R16C:$rA), i32ImmSExt10:$val))]>;
1150
1151// Bitwise OR group:
1152// Bitwise "or" (N.B.: These are also register-register copy instructions...)
1153def ORv16i8:
1154 RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1155 "or\t$rT, $rA, $rB", IntegerOp,
1156 [(set (v16i8 VECREG:$rT), (or (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
1157
1158def ORv8i16:
1159 RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1160 "or\t$rT, $rA, $rB", IntegerOp,
1161 [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
1162
1163def ORv4i32:
1164 RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1165 "or\t$rT, $rA, $rB", IntegerOp,
1166 [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
1167
1168def ORv4f32:
1169 RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1170 "or\t$rT, $rA, $rB", IntegerOp,
1171 [(set (v4f32 VECREG:$rT),
1172 (v4f32 (bitconvert (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))))]>;
1173
1174def ORv2f64:
1175 RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1176 "or\t$rT, $rA, $rB", IntegerOp,
1177 [(set (v2f64 VECREG:$rT),
1178 (v2f64 (bitconvert (or (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)))))]>;
1179
1180def ORgprc:
1181 RRForm<0b10000010000, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB),
1182 "or\t$rT, $rA, $rB", IntegerOp,
1183 [(set GPRC:$rT, (or GPRC:$rA, GPRC:$rB))]>;
1184
1185def ORr64:
1186 RRForm<0b10000010000, (outs R64C:$rT), (ins R64C:$rA, R64C:$rB),
1187 "or\t$rT, $rA, $rB", IntegerOp,
1188 [(set R64C:$rT, (or R64C:$rA, R64C:$rB))]>;
1189
1190def ORr32:
1191 RRForm<0b10000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1192 "or\t$rT, $rA, $rB", IntegerOp,
1193 [(set R32C:$rT, (or R32C:$rA, R32C:$rB))]>;
1194
1195def ORr16:
1196 RRForm<0b10000010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1197 "or\t$rT, $rA, $rB", IntegerOp,
1198 [(set R16C:$rT, (or R16C:$rA, R16C:$rB))]>;
1199
1200// ORv*_*: Used in scalar->vector promotions:
1201def ORv8i16_i16:
1202 RRForm<0b10000010000, (outs VECREG:$rT), (ins R16C:$rA, R16C:$rB),
1203 "or\t$rT, $rA, $rB", IntegerOp,
1204 [/* no pattern */]>;
1205
1206def : Pat<(v8i16 (SPUpromote_scalar R16C:$rA)),
1207 (ORv8i16_i16 R16C:$rA, R16C:$rA)>;
1208
1209def ORv4i32_i32:
1210 RRForm<0b10000010000, (outs VECREG:$rT), (ins R32C:$rA, R32C:$rB),
1211 "or\t$rT, $rA, $rB", IntegerOp,
1212 [/* no pattern */]>;
1213
1214def : Pat<(v4i32 (SPUpromote_scalar R32C:$rA)),
1215 (ORv4i32_i32 R32C:$rA, R32C:$rA)>;
1216
1217def ORv2i64_i64:
1218 RRForm<0b10000010000, (outs VECREG:$rT), (ins R64C:$rA, R64C:$rB),
1219 "or\t$rT, $rA, $rB", IntegerOp,
1220 [/* no pattern */]>;
1221
1222def : Pat<(v2i64 (SPUpromote_scalar R64C:$rA)),
1223 (ORv2i64_i64 R64C:$rA, R64C:$rA)>;
1224
1225def ORv4f32_f32:
1226 RRForm<0b10000010000, (outs VECREG:$rT), (ins R32FP:$rA, R32FP:$rB),
1227 "or\t$rT, $rA, $rB", IntegerOp,
1228 [/* no pattern */]>;
1229
1230def : Pat<(v4f32 (SPUpromote_scalar R32FP:$rA)),
1231 (ORv4f32_f32 R32FP:$rA, R32FP:$rA)>;
1232
1233def ORv2f64_f64:
1234 RRForm<0b10000010000, (outs VECREG:$rT), (ins R64FP:$rA, R64FP:$rB),
1235 "or\t$rT, $rA, $rB", IntegerOp,
1236 [/* no pattern */]>;
1237
1238def : Pat<(v2f64 (SPUpromote_scalar R64FP:$rA)),
1239 (ORv2f64_f64 R64FP:$rA, R64FP:$rA)>;
1240
1241// ORi*_v*: Used to extract vector element 0 (the preferred slot)
1242def ORi16_v8i16:
1243 RRForm<0b10000010000, (outs R16C:$rT), (ins VECREG:$rA, VECREG:$rB),
1244 "or\t$rT, $rA, $rB", IntegerOp,
1245 [/* no pattern */]>;
1246
1247def : Pat<(SPUextract_elt0 (v8i16 VECREG:$rA)),
1248 (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>;
1249
1250def : Pat<(SPUextract_elt0_chained (v8i16 VECREG:$rA)),
1251 (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>;
1252
1253def ORi32_v4i32:
1254 RRForm<0b10000010000, (outs R32C:$rT), (ins VECREG:$rA, VECREG:$rB),
1255 "or\t$rT, $rA, $rB", IntegerOp,
1256 [/* no pattern */]>;
1257
1258def : Pat<(SPUextract_elt0 (v4i32 VECREG:$rA)),
1259 (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>;
1260
1261def : Pat<(SPUextract_elt0_chained (v4i32 VECREG:$rA)),
1262 (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>;
1263
1264def ORi64_v2i64:
1265 RRForm<0b10000010000, (outs R64C:$rT), (ins VECREG:$rA, VECREG:$rB),
1266 "or\t$rT, $rA, $rB", IntegerOp,
1267 [/* no pattern */]>;
1268
1269def : Pat<(SPUextract_elt0 (v2i64 VECREG:$rA)),
1270 (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>;
1271
1272def : Pat<(SPUextract_elt0_chained (v2i64 VECREG:$rA)),
1273 (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>;
1274
1275def ORf32_v4f32:
1276 RRForm<0b10000010000, (outs R32FP:$rT), (ins VECREG:$rA, VECREG:$rB),
1277 "or\t$rT, $rA, $rB", IntegerOp,
1278 [/* no pattern */]>;
1279
1280def : Pat<(SPUextract_elt0 (v4f32 VECREG:$rA)),
1281 (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>;
1282
1283def : Pat<(SPUextract_elt0_chained (v4f32 VECREG:$rA)),
1284 (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>;
1285
1286def ORf64_v2f64:
1287 RRForm<0b10000010000, (outs R64FP:$rT), (ins VECREG:$rA, VECREG:$rB),
1288 "or\t$rT, $rA, $rB", IntegerOp,
1289 [/* no pattern */]>;
1290
1291def : Pat<(SPUextract_elt0 (v2f64 VECREG:$rA)),
1292 (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>;
1293
1294def : Pat<(SPUextract_elt0_chained (v2f64 VECREG:$rA)),
1295 (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>;
1296
1297// ORC: Bitwise "or" with complement (match before ORvec, ORr32)
1298def ORCv16i8:
1299 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1300 "orc\t$rT, $rA, $rB", IntegerOp,
1301 [(set (v16i8 VECREG:$rT), (or (v16i8 VECREG:$rA),
1302 (vnot (v16i8 VECREG:$rB))))]>;
1303
1304def ORCv8i16:
1305 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1306 "orc\t$rT, $rA, $rB", IntegerOp,
1307 [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA),
1308 (vnot (v8i16 VECREG:$rB))))]>;
1309
1310def ORCv4i32:
1311 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1312 "orc\t$rT, $rA, $rB", IntegerOp,
1313 [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA),
1314 (vnot (v4i32 VECREG:$rB))))]>;
1315
1316def ORCr32:
1317 RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1318 "orc\t$rT, $rA, $rB", IntegerOp,
1319 [(set R32C:$rT, (or R32C:$rA, (not R32C:$rB)))]>;
1320
1321def ORCr16:
1322 RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1323 "orc\t$rT, $rA, $rB", IntegerOp,
1324 [(set R16C:$rT, (or R16C:$rA, (not R16C:$rB)))]>;
1325
1326// OR byte immediate
1327def ORBIv16i8:
1328 RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
1329 "orbi\t$rT, $rA, $val", IntegerOp,
1330 [(set (v16i8 VECREG:$rT),
1331 (or (v16i8 VECREG:$rA), (v16i8 v16i8U8Imm:$val)))]>;
1332
1333// OR halfword immediate
1334def ORHIv8i16:
1335 RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1336 "orhi\t$rT, $rA, $val", IntegerOp,
1337 [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA),
1338 v8i16SExt10Imm:$val))]>;
1339
1340def ORHIr16:
1341 RI10Form<0b10100000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
1342 "orhi\t$rT, $rA, $val", IntegerOp,
1343 [(set R16C:$rT, (or R16C:$rA, i16ImmSExt10:$val))]>;
1344
1345// Bitwise "or" with immediate
1346def ORIv4i32:
1347 RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1348 "ori\t$rT, $rA, $val", IntegerOp,
1349 [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA),
1350 v4i32SExt10Imm:$val))]>;
1351
1352def ORIr32:
1353 RI10Form<0b00100000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val),
1354 "ori\t$rT, $rA, $val", IntegerOp,
1355 [(set R32C:$rT, (or R32C:$rA, i32ImmSExt10:$val))]>;
1356
1357// Hacked forms of or immediate to copy one 32- and 64-bit FP register
1358// to another. Do not match patterns.
1359def ORIf32:
1360 RI10Form_1<0b00100000, (outs R32FP:$rT), (ins R32FP:$rA, s10imm_i32:$val),
1361 "ori\t$rT, $rA, $val", IntegerOp,
1362 [/* no pattern */]>;
1363
1364def ORIf64:
1365 RI10Form_1<0b00100000, (outs R64FP:$rT), (ins R64FP:$rA, s10imm_i32:$val),
1366 "ori\t$rT, $rA, $val", IntegerOp,
1367 [/* no pattern */]>;
1368
1369def ORIr64:
1370 RI10Form_1<0b00100000, (outs R64C:$rT), (ins R64C:$rA, s10imm_i32:$val),
1371 "ori\t$rT, $rA, $val", IntegerOp,
1372 [/* no pattern */]>;
1373
1374// ORI2To4: hacked version of the ori instruction to extend 16-bit quantities
1375// to 32-bit quantities. used exclusively to match "anyext" conversions (vide
1376// infra "anyext 16->32" pattern.)
1377def ORI2To4:
1378 RI10Form<0b00100000, (outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val),
1379 "ori\t$rT, $rA, $val", IntegerOp,
1380 [(set R32C:$rT, (or (anyext R16C:$rA), i32ImmSExt10:$val))]>;
1381
1382// ORX: "or" across the vector: or's $rA's word slots leaving the result in
1383// $rT[0], slots 1-3 are zeroed.
1384//
1385// Needs to match an intrinsic pattern.
1386def ORXv4i32:
1387 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1388 "orx\t$rT, $rA, $rB", IntegerOp,
1389 []>;
1390
1391def XORv16i8:
1392 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1393 "xor\t$rT, $rA, $rB", IntegerOp,
1394 [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
1395
1396def XORv8i16:
1397 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1398 "xor\t$rT, $rA, $rB", IntegerOp,
1399 [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
1400
1401def XORv4i32:
1402 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1403 "xor\t$rT, $rA, $rB", IntegerOp,
1404 [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
1405
1406def XORr32:
1407 RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1408 "xor\t$rT, $rA, $rB", IntegerOp,
1409 [(set R32C:$rT, (xor R32C:$rA, R32C:$rB))]>;
1410
1411//==----------------------------------------------------------
1412// Special forms for floating point instructions.
1413// Bitwise ORs and ANDs don't make sense for normal floating
1414// point numbers. These operations (fneg and fabs), however,
1415// require bitwise logical ops to manipulate the sign bit.
1416def XORfneg32:
1417 RRForm<0b10010010000, (outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
1418 "xor\t$rT, $rA, $rB", IntegerOp,
1419 [/* Intentionally does not match a pattern, see fneg32 */]>;
1420
1421// KLUDGY! Better way to do this without a VECREG? bitconvert?
1422// VECREG is assumed to contain two identical 64-bit masks, so
1423// it doesn't matter which word we select for the xor
1424def XORfneg64:
1425 RRForm<0b10010010000, (outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
1426 "xor\t$rT, $rA, $rB", IntegerOp,
1427 [/* Intentionally does not match a pattern, see fneg64 */]>;
1428
1429// Could use XORv4i32, but will use this for clarity
1430def XORfnegvec:
1431 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1432 "xor\t$rT, $rA, $rB", IntegerOp,
1433 [/* Intentionally does not match a pattern, see fneg{32,64} */]>;
1434
1435//==----------------------------------------------------------
1436
1437def XORr16:
1438 RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1439 "xor\t$rT, $rA, $rB", IntegerOp,
1440 [(set R16C:$rT, (xor R16C:$rA, R16C:$rB))]>;
1441
1442def XORBIv16i8:
1443 RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
1444 "xorbi\t$rT, $rA, $val", IntegerOp,
1445 [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), v16i8U8Imm:$val))]>;
1446
1447def XORHIv8i16:
1448 RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1449 "xorhi\t$rT, $rA, $val", IntegerOp,
1450 [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA),
1451 v8i16SExt10Imm:$val))]>;
1452
1453def XORHIr16:
1454 RI10Form<0b10100000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
1455 "xorhi\t$rT, $rA, $val", IntegerOp,
1456 [(set R16C:$rT, (xor R16C:$rA, i16ImmSExt10:$val))]>;
1457
1458def XORIv4i32:
1459 RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
1460 "xori\t$rT, $rA, $val", IntegerOp,
1461 [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA),
1462 v4i32SExt10Imm:$val))]>;
1463
1464def XORIr32:
1465 RI10Form<0b00100000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val),
1466 "xori\t$rT, $rA, $val", IntegerOp,
1467 [(set R32C:$rT, (xor R32C:$rA, i32ImmSExt10:$val))]>;
1468
1469// NAND:
1470def NANDv16i8:
1471 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1472 "nand\t$rT, $rA, $rB", IntegerOp,
1473 [(set (v16i8 VECREG:$rT), (vnot (and (v16i8 VECREG:$rA),
1474 (v16i8 VECREG:$rB))))]>;
1475
1476def NANDv8i16:
1477 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1478 "nand\t$rT, $rA, $rB", IntegerOp,
1479 [(set (v8i16 VECREG:$rT), (vnot (and (v8i16 VECREG:$rA),
1480 (v8i16 VECREG:$rB))))]>;
1481
1482def NANDv4i32:
1483 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1484 "nand\t$rT, $rA, $rB", IntegerOp,
1485 [(set (v4i32 VECREG:$rT), (vnot (and (v4i32 VECREG:$rA),
1486 (v4i32 VECREG:$rB))))]>;
1487
1488def NANDr32:
1489 RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1490 "nand\t$rT, $rA, $rB", IntegerOp,
1491 [(set R32C:$rT, (not (and R32C:$rA, R32C:$rB)))]>;
1492
1493def NANDr16:
1494 RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1495 "nand\t$rT, $rA, $rB", IntegerOp,
1496 [(set R16C:$rT, (not (and R16C:$rA, R16C:$rB)))]>;
1497
1498// NOR:
1499def NORv16i8:
1500 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1501 "nor\t$rT, $rA, $rB", IntegerOp,
1502 [(set (v16i8 VECREG:$rT), (vnot (or (v16i8 VECREG:$rA),
1503 (v16i8 VECREG:$rB))))]>;
1504
1505def NORv8i16:
1506 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1507 "nor\t$rT, $rA, $rB", IntegerOp,
1508 [(set (v8i16 VECREG:$rT), (vnot (or (v8i16 VECREG:$rA),
1509 (v8i16 VECREG:$rB))))]>;
1510
1511def NORv4i32:
1512 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1513 "nor\t$rT, $rA, $rB", IntegerOp,
1514 [(set (v4i32 VECREG:$rT), (vnot (or (v4i32 VECREG:$rA),
1515 (v4i32 VECREG:$rB))))]>;
1516
1517def NORr32:
1518 RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1519 "nor\t$rT, $rA, $rB", IntegerOp,
1520 [(set R32C:$rT, (not (or R32C:$rA, R32C:$rB)))]>;
1521
1522def NORr16:
1523 RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1524 "nor\t$rT, $rA, $rB", IntegerOp,
1525 [(set R16C:$rT, (not (or R16C:$rA, R16C:$rB)))]>;
1526
1527// EQV: Equivalence (1 for each same bit, otherwise 0)
1528def EQVv16i8:
1529 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1530 "eqv\t$rT, $rA, $rB", IntegerOp,
1531 [(set (v16i8 VECREG:$rT), (or (and (v16i8 VECREG:$rA),
1532 (v16i8 VECREG:$rB)),
1533 (and (vnot (v16i8 VECREG:$rA)),
1534 (vnot (v16i8 VECREG:$rB)))))]>;
1535
1536def : Pat<(xor (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rB))),
1537 (EQVv16i8 VECREG:$rA, VECREG:$rB)>;
1538
1539def : Pat<(xor (vnot (v16i8 VECREG:$rA)), (v16i8 VECREG:$rB)),
1540 (EQVv16i8 VECREG:$rA, VECREG:$rB)>;
1541
1542def EQVv8i16:
1543 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1544 "eqv\t$rT, $rA, $rB", IntegerOp,
1545 [(set (v8i16 VECREG:$rT), (or (and (v8i16 VECREG:$rA),
1546 (v8i16 VECREG:$rB)),
1547 (and (vnot (v8i16 VECREG:$rA)),
1548 (vnot (v8i16 VECREG:$rB)))))]>;
1549
1550def : Pat<(xor (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rB))),
1551 (EQVv8i16 VECREG:$rA, VECREG:$rB)>;
1552
1553def : Pat<(xor (vnot (v8i16 VECREG:$rA)), (v8i16 VECREG:$rB)),
1554 (EQVv8i16 VECREG:$rA, VECREG:$rB)>;
1555
1556def EQVv4i32:
1557 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
1558 "eqv\t$rT, $rA, $rB", IntegerOp,
1559 [(set (v4i32 VECREG:$rT), (or (and (v4i32 VECREG:$rA),
1560 (v4i32 VECREG:$rB)),
1561 (and (vnot (v4i32 VECREG:$rA)),
1562 (vnot (v4i32 VECREG:$rB)))))]>;
1563
1564def : Pat<(xor (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rB))),
1565 (EQVv4i32 VECREG:$rA, VECREG:$rB)>;
1566
1567def : Pat<(xor (vnot (v4i32 VECREG:$rA)), (v4i32 VECREG:$rB)),
1568 (EQVv4i32 VECREG:$rA, VECREG:$rB)>;
1569
1570def EQVr32:
1571 RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1572 "eqv\t$rT, $rA, $rB", IntegerOp,
1573 [(set R32C:$rT, (or (and R32C:$rA, R32C:$rB),
1574 (and (not R32C:$rA), (not R32C:$rB))))]>;
1575
1576def : Pat<(xor R32C:$rA, (not R32C:$rB)),
1577 (EQVr32 R32C:$rA, R32C:$rB)>;
1578
1579def : Pat<(xor (not R32C:$rA), R32C:$rB),
1580 (EQVr32 R32C:$rA, R32C:$rB)>;
1581
1582def EQVr16:
1583 RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1584 "eqv\t$rT, $rA, $rB", IntegerOp,
1585 [(set R16C:$rT, (or (and R16C:$rA, R16C:$rB),
1586 (and (not R16C:$rA), (not R16C:$rB))))]>;
1587
1588def : Pat<(xor R16C:$rA, (not R16C:$rB)),
1589 (EQVr16 R16C:$rA, R16C:$rB)>;
1590
1591def : Pat<(xor (not R16C:$rA), R16C:$rB),
1592 (EQVr16 R16C:$rA, R16C:$rB)>;
1593
1594// gcc optimizes (p & q) | (~p & ~q) -> ~(p | q) | (p & q), so match that
1595// pattern also:
1596def : Pat<(or (vnot (or (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))),
1597 (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))),
1598 (EQVv16i8 VECREG:$rA, VECREG:$rB)>;
1599
1600def : Pat<(or (vnot (or (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))),
1601 (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))),
1602 (EQVv8i16 VECREG:$rA, VECREG:$rB)>;
1603
1604def : Pat<(or (vnot (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))),
1605 (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))),
1606 (EQVv4i32 VECREG:$rA, VECREG:$rB)>;
1607
1608def : Pat<(or (not (or R32C:$rA, R32C:$rB)), (and R32C:$rA, R32C:$rB)),
1609 (EQVr32 R32C:$rA, R32C:$rB)>;
1610
1611def : Pat<(or (not (or R16C:$rA, R16C:$rB)), (and R16C:$rA, R16C:$rB)),
1612 (EQVr16 R16C:$rA, R16C:$rB)>;
1613
1614// Select bits:
1615def SELBv16i8:
1616 RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
1617 "selb\t$rT, $rA, $rB, $rC", IntegerOp,
1618 [(set (v16i8 VECREG:$rT),
1619 (SPUselb_v16i8 (v16i8 VECREG:$rA), (v16i8 VECREG:$rB),
1620 (v16i8 VECREG:$rC)))]>;
1621
1622def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)),
1623 (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))),
1624 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1625
1626def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)),
1627 (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))),
1628 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1629
1630def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)),
1631 (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))),
1632 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1633
1634def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)),
1635 (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))),
1636 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1637
1638def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))),
1639 (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))),
1640 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1641
1642def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))),
1643 (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))),
1644 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1645
1646def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)),
1647 (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))),
1648 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1649
1650def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)),
1651 (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))),
1652 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1653
1654def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)),
1655 (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))),
1656 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1657
1658def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)),
1659 (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))),
1660 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1661
1662def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)),
1663 (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))),
1664 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1665
1666def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)),
1667 (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))),
1668 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1669
1670def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))),
1671 (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))),
1672 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1673
1674def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))),
1675 (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))),
1676 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1677
1678def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)),
1679 (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))),
1680 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1681
1682def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)),
1683 (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))),
1684 (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1685
1686def SELBv8i16:
1687 RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
1688 "selb\t$rT, $rA, $rB, $rC", IntegerOp,
1689 [(set (v8i16 VECREG:$rT),
1690 (SPUselb_v8i16 (v8i16 VECREG:$rA), (v8i16 VECREG:$rB),
1691 (v8i16 VECREG:$rC)))]>;
1692
1693def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)),
1694 (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))),
1695 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1696
1697def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)),
1698 (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))),
1699 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1700
1701def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)),
1702 (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))),
1703 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1704
1705def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)),
1706 (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))),
1707 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1708
1709def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))),
1710 (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))),
1711 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1712
1713def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))),
1714 (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))),
1715 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1716
1717def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)),
1718 (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))),
1719 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1720
1721def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)),
1722 (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))),
1723 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1724
1725def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)),
1726 (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))),
1727 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1728
1729def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)),
1730 (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))),
1731 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1732
1733def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)),
1734 (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))),
1735 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1736
1737def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)),
1738 (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))),
1739 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1740
1741def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))),
1742 (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))),
1743 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1744
1745def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))),
1746 (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))),
1747 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1748
1749def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)),
1750 (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))),
1751 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1752
1753def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)),
1754 (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))),
1755 (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1756
1757def SELBv4i32:
1758 RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
1759 "selb\t$rT, $rA, $rB, $rC", IntegerOp,
1760 [(set (v4i32 VECREG:$rT),
1761 (SPUselb_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB),
1762 (v4i32 VECREG:$rC)))]>;
1763
1764def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)),
1765 (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))),
1766 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1767
1768def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)),
1769 (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))),
1770 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1771
1772def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)),
1773 (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))),
1774 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1775
1776def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)),
1777 (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))),
1778 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1779
1780def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))),
1781 (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))),
1782 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1783
1784def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))),
1785 (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))),
1786 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1787
1788def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)),
1789 (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))),
1790 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1791
1792def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)),
1793 (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))),
1794 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1795
1796def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)),
1797 (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))),
1798 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1799
1800def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)),
1801 (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))),
1802 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1803
1804def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)),
1805 (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))),
1806 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1807
1808def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)),
1809 (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))),
1810 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1811
1812def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))),
1813 (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))),
1814 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1815
1816def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))),
1817 (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))),
1818 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1819
1820def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)),
1821 (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))),
1822 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1823
1824def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)),
1825 (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))),
1826 (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1827
1828def SELBr32:
1829 RRRForm<0b1000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC),
1830 "selb\t$rT, $rA, $rB, $rC", IntegerOp,
1831 []>;
1832
1833// And the various patterns that can be matched... (all 8 of them :-)
1834def : Pat<(or (and R32C:$rA, R32C:$rC),
1835 (and R32C:$rB, (not R32C:$rC))),
1836 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1837
1838def : Pat<(or (and R32C:$rC, R32C:$rA),
1839 (and R32C:$rB, (not R32C:$rC))),
1840 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1841
1842def : Pat<(or (and R32C:$rA, R32C:$rC),
1843 (and (not R32C:$rC), R32C:$rB)),
1844 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1845
1846def : Pat<(or (and R32C:$rC, R32C:$rA),
1847 (and (not R32C:$rC), R32C:$rB)),
1848 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1849
1850def : Pat<(or (and R32C:$rA, (not R32C:$rC)),
1851 (and R32C:$rB, R32C:$rC)),
1852 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1853
1854def : Pat<(or (and R32C:$rA, (not R32C:$rC)),
1855 (and R32C:$rC, R32C:$rB)),
1856 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1857
1858def : Pat<(or (and (not R32C:$rC), R32C:$rA),
1859 (and R32C:$rB, R32C:$rC)),
1860 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1861
1862def : Pat<(or (and (not R32C:$rC), R32C:$rA),
1863 (and R32C:$rC, R32C:$rB)),
1864 (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>;
1865
1866def SELBr16:
1867 RRRForm<0b1000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB, R16C:$rC),
1868 "selb\t$rT, $rA, $rB, $rC", IntegerOp,
1869 []>;
1870
1871def : Pat<(or (and R16C:$rA, R16C:$rC),
1872 (and R16C:$rB, (not R16C:$rC))),
1873 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1874
1875def : Pat<(or (and R16C:$rC, R16C:$rA),
1876 (and R16C:$rB, (not R16C:$rC))),
1877 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1878
1879def : Pat<(or (and R16C:$rA, R16C:$rC),
1880 (and (not R16C:$rC), R16C:$rB)),
1881 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1882
1883def : Pat<(or (and R16C:$rC, R16C:$rA),
1884 (and (not R16C:$rC), R16C:$rB)),
1885 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1886
1887def : Pat<(or (and R16C:$rA, (not R16C:$rC)),
1888 (and R16C:$rB, R16C:$rC)),
1889 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1890
1891def : Pat<(or (and R16C:$rA, (not R16C:$rC)),
1892 (and R16C:$rC, R16C:$rB)),
1893 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1894
1895def : Pat<(or (and (not R16C:$rC), R16C:$rA),
1896 (and R16C:$rB, R16C:$rC)),
1897 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1898
1899def : Pat<(or (and (not R16C:$rC), R16C:$rA),
1900 (and R16C:$rC, R16C:$rB)),
1901 (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>;
1902
1903//===----------------------------------------------------------------------===//
1904// Vector shuffle...
1905//===----------------------------------------------------------------------===//
1906
1907def SHUFB:
1908 RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
1909 "shufb\t$rT, $rA, $rB, $rC", IntegerOp,
1910 [/* insert intrinsic here */]>;
1911
1912// SPUshuffle is generated in LowerVECTOR_SHUFFLE and gets replaced with SHUFB.
1913// See the SPUshuffle SDNode operand above, which sets up the DAG pattern
1914// matcher to emit something when the LowerVECTOR_SHUFFLE generates a node with
1915// the SPUISD::SHUFB opcode.
1916def : Pat<(SPUshuffle (v16i8 VECREG:$rA), (v16i8 VECREG:$rB), VECREG:$rC),
1917 (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1918
1919def : Pat<(SPUshuffle (v8i16 VECREG:$rA), (v8i16 VECREG:$rB), VECREG:$rC),
1920 (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1921
1922def : Pat<(SPUshuffle (v4i32 VECREG:$rA), (v4i32 VECREG:$rB), VECREG:$rC),
1923 (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1924
1925def : Pat<(SPUshuffle (v2i64 VECREG:$rA), (v2i64 VECREG:$rB), VECREG:$rC),
1926 (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
1927
1928//===----------------------------------------------------------------------===//
1929// Shift and rotate group:
1930//===----------------------------------------------------------------------===//
1931
1932def SHLHv8i16:
1933 RRForm<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB),
1934 "shlh\t$rT, $rA, $rB", RotateShift,
1935 [(set (v8i16 VECREG:$rT),
1936 (SPUvec_shl_v8i16 (v8i16 VECREG:$rA), R16C:$rB))]>;
1937
1938// $rB gets promoted to 32-bit register type when confronted with
1939// this llvm assembly code:
1940//
1941// define i16 @shlh_i16_1(i16 %arg1, i16 %arg2) {
1942// %A = shl i16 %arg1, %arg2
1943// ret i16 %A
1944// }
1945//
1946// However, we will generate this code when lowering 8-bit shifts and rotates.
1947
1948def SHLHr16:
1949 RRForm<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
1950 "shlh\t$rT, $rA, $rB", RotateShift,
1951 [(set R16C:$rT, (shl R16C:$rA, R16C:$rB))]>;
1952
1953def SHLHr16_r32:
1954 RRForm<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB),
1955 "shlh\t$rT, $rA, $rB", RotateShift,
1956 [(set R16C:$rT, (shl R16C:$rA, R32C:$rB))]>;
1957
1958def SHLHIv8i16:
1959 RI7Form<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
1960 "shlhi\t$rT, $rA, $val", RotateShift,
1961 [(set (v8i16 VECREG:$rT),
1962 (SPUvec_shl_v8i16 (v8i16 VECREG:$rA), (i16 uimm7:$val)))]>;
1963
1964def : Pat<(SPUvec_shl_v8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val)),
1965 (SHLHIv8i16 VECREG:$rA, imm:$val)>;
1966
1967def SHLHIr16:
1968 RI7Form<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, u7imm_i32:$val),
1969 "shlhi\t$rT, $rA, $val", RotateShift,
1970 [(set R16C:$rT, (shl R16C:$rA, (i32 uimm7:$val)))]>;
1971
1972def : Pat<(shl R16C:$rA, (i16 uimm7:$val)),
1973 (SHLHIr16 R16C:$rA, uimm7:$val)>;
1974
1975def SHLv4i32:
1976 RRForm<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB),
1977 "shl\t$rT, $rA, $rB", RotateShift,
1978 [(set (v4i32 VECREG:$rT),
1979 (SPUvec_shl_v4i32 (v4i32 VECREG:$rA), R16C:$rB))]>;
1980
1981def SHLr32:
1982 RRForm<0b11111010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
1983 "shl\t$rT, $rA, $rB", RotateShift,
1984 [(set R32C:$rT, (shl R32C:$rA, R32C:$rB))]>;
1985
1986def SHLIv4i32:
1987 RI7Form<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
1988 "shli\t$rT, $rA, $val", RotateShift,
1989 [(set (v4i32 VECREG:$rT),
1990 (SPUvec_shl_v4i32 (v4i32 VECREG:$rA), (i16 uimm7:$val)))]>;
1991
1992def: Pat<(SPUvec_shl_v4i32 (v4i32 VECREG:$rA), (i32 uimm7:$val)),
1993 (SHLIv4i32 VECREG:$rA, uimm7:$val)>;
1994
1995def SHLIr32:
1996 RI7Form<0b11111010000, (outs R32C:$rT), (ins R32C:$rA, u7imm_i32:$val),
1997 "shli\t$rT, $rA, $val", RotateShift,
1998 [(set R32C:$rT, (shl R32C:$rA, (i32 uimm7:$val)))]>;
1999
2000def : Pat<(shl R32C:$rA, (i16 uimm7:$val)),
2001 (SHLIr32 R32C:$rA, uimm7:$val)>;
2002
2003// SHLQBI vec form: Note that this will shift the entire vector (the 128-bit
2004// register) to the left. Vector form is here to ensure type correctness.
2005def SHLQBIvec:
2006 RRForm<0b11011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2007 "shlqbi\t$rT, $rA, $rB", RotateShift,
2008 [/* intrinsic */]>;
2009
2010// See note above on SHLQBI.
2011def SHLQBIIvec:
2012 RI7Form<0b11011111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
2013 "shlqbii\t$rT, $rA, $val", RotateShift,
2014 [/* intrinsic */]>;
2015
2016// SHLQBY, SHLQBYI vector forms: Shift the entire vector to the left by bytes,
2017// not by bits.
2018def SHLQBYvec:
2019 RI7Form<0b11111011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2020 "shlqbyi\t$rT, $rA, $rB", RotateShift,
2021 [/* intrinsic */]>;
2022
2023def SHLQBYIvec:
2024 RI7Form<0b11111111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
2025 "shlqbyi\t$rT, $rA, $val", RotateShift,
2026 [/* intrinsic */]>;
2027
2028// ROTH v8i16 form:
2029def ROTHv8i16:
2030 RRForm<0b00111010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2031 "roth\t$rT, $rA, $rB", RotateShift,
2032 [(set (v8i16 VECREG:$rT),
2033 (SPUvec_rotl_v8i16 VECREG:$rA, VECREG:$rB))]>;
2034
2035def ROTHr16:
2036 RRForm<0b00111010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
2037 "roth\t$rT, $rA, $rB", RotateShift,
2038 [(set R16C:$rT, (rotl R16C:$rA, R16C:$rB))]>;
2039
2040def ROTHr16_r32:
2041 RRForm<0b00111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB),
2042 "roth\t$rT, $rA, $rB", RotateShift,
2043 [(set R16C:$rT, (rotl R16C:$rA, R32C:$rB))]>;
2044
2045def ROTHIv8i16:
2046 RI7Form<0b00111110000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
2047 "rothi\t$rT, $rA, $val", RotateShift,
2048 [(set (v8i16 VECREG:$rT),
2049 (SPUvec_rotl_v8i16 VECREG:$rA, (i16 uimm7:$val)))]>;
2050
2051def : Pat<(SPUvec_rotl_v8i16 VECREG:$rA, (i16 uimm7:$val)),
2052 (ROTHIv8i16 VECREG:$rA, imm:$val)>;
2053
2054def : Pat<(SPUvec_rotl_v8i16 VECREG:$rA, (i32 uimm7:$val)),
2055 (ROTHIv8i16 VECREG:$rA, imm:$val)>;
2056
2057def ROTHIr16:
2058 RI7Form<0b00111110000, (outs R16C:$rT), (ins R16C:$rA, u7imm:$val),
2059 "rothi\t$rT, $rA, $val", RotateShift,
2060 [(set R16C:$rT, (rotl R16C:$rA, (i16 uimm7:$val)))]>;
2061
2062def ROTHIr16_i32:
2063 RI7Form<0b00111110000, (outs R16C:$rT), (ins R16C:$rA, u7imm_i32:$val),
2064 "rothi\t$rT, $rA, $val", RotateShift,
2065 [(set R16C:$rT, (rotl R16C:$rA, (i32 uimm7:$val)))]>;
2066
2067def ROTv4i32:
2068 RRForm<0b00011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2069 "rot\t$rT, $rA, $rB", RotateShift,
2070 [(set (v4i32 VECREG:$rT),
2071 (SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), R32C:$rB))]>;
2072
2073def ROTr32:
2074 RRForm<0b00011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
2075 "rot\t$rT, $rA, $rB", RotateShift,
2076 [(set R32C:$rT, (rotl R32C:$rA, R32C:$rB))]>;
2077
2078def ROTIv4i32:
2079 RI7Form<0b00011110000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val),
2080 "roti\t$rT, $rA, $val", RotateShift,
2081 [(set (v4i32 VECREG:$rT),
2082 (SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), (i32 uimm7:$val)))]>;
2083
2084def : Pat<(SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), (i16 uimm7:$val)),
2085 (ROTIv4i32 VECREG:$rA, imm:$val)>;
2086
2087def ROTIr32:
2088 RI7Form<0b00011110000, (outs R32C:$rT), (ins R32C:$rA, u7imm_i32:$val),
2089 "roti\t$rT, $rA, $val", RotateShift,
2090 [(set R32C:$rT, (rotl R32C:$rA, (i32 uimm7:$val)))]>;
2091
2092def ROTIr32_i16:
2093 RI7Form<0b00111110000, (outs R32C:$rT), (ins R32C:$rA, u7imm:$val),
2094 "roti\t$rT, $rA, $val", RotateShift,
2095 [(set R32C:$rT, (rotl R32C:$rA, (i16 uimm7:$val)))]>;
2096
2097// ROTQBY* vector forms: This rotates the entire vector, but vector registers
2098// are used here for type checking (instances where ROTQBI is used actually
2099// use vector registers)
2100def ROTQBYvec:
2101 RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB),
2102 "rotqby\t$rT, $rA, $rB", RotateShift,
2103 [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R16C:$rB))]>;
2104
2105def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R16C:$rB),
2106 (ROTQBYvec VECREG:$rA, R16C:$rB)>;
2107
2108// See ROTQBY note above.
2109def ROTQBYIvec:
2110 RI7Form<0b00111111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
2111 "rotqbyi\t$rT, $rA, $val", RotateShift,
2112 [(set (v16i8 VECREG:$rT),
2113 (SPUrotbytes_left (v16i8 VECREG:$rA), (i16 uimm7:$val)))]>;
2114
2115def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), (i16 uimm7:$val)),
2116 (ROTQBYIvec VECREG:$rA, uimm7:$val)>;
2117
2118// See ROTQBY note above.
2119def ROTQBYBIvec:
2120 RI7Form<0b00110011100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val),
2121 "rotqbybi\t$rT, $rA, $val", RotateShift,
2122 [/* intrinsic */]>;
2123
2124// See ROTQBY note above.
2125//
2126// Assume that the user of this instruction knows to shift the rotate count
2127// into bit 29
2128def ROTQBIvec:
2129 RRForm<0b00011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2130 "rotqbi\t$rT, $rA, $rB", RotateShift,
2131 [/* insert intrinsic here */]>;
2132
2133// See ROTQBY note above.
2134def ROTQBIIvec:
2135 RI7Form<0b00011111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val),
2136 "rotqbii\t$rT, $rA, $val", RotateShift,
2137 [/* insert intrinsic here */]>;
2138
2139// ROTHM v8i16 form:
2140// NOTE(1): No vector rotate is generated by the C/C++ frontend (today),
2141// so this only matches a synthetically generated/lowered code
2142// fragment.
2143// NOTE(2): $rB must be negated before the right rotate!
2144def ROTHMv8i16:
2145 RRForm<0b10111010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2146 "rothm\t$rT, $rA, $rB", RotateShift,
2147 [/* see patterns below - $rB must be negated */]>;
2148
2149def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), R32C:$rB),
2150 (ROTHMv8i16 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
2151
2152def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), R16C:$rB),
2153 (ROTHMv8i16 VECREG:$rA,
2154 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2155
2156def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), /* R8C */ R16C:$rB),
2157 (ROTHMv8i16 VECREG:$rA,
2158 (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /*)*/, 0))>;
2159
2160// ROTHM r16 form: Rotate 16-bit quantity to right, zero fill at the left
2161// Note: This instruction doesn't match a pattern because rB must be negated
2162// for the instruction to work. Thus, the pattern below the instruction!
2163def ROTHMr16:
2164 RRForm<0b10111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB),
2165 "rothm\t$rT, $rA, $rB", RotateShift,
2166 [/* see patterns below - $rB must be negated! */]>;
2167
2168def : Pat<(srl R16C:$rA, R32C:$rB),
2169 (ROTHMr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>;
2170
2171def : Pat<(srl R16C:$rA, R16C:$rB),
2172 (ROTHMr16 R16C:$rA,
2173 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2174
2175def : Pat<(srl R16C:$rA, /* R8C */ R16C:$rB),
2176 (ROTHMr16 R16C:$rA,
2177 (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /* ) */, 0))>;
2178
2179// ROTHMI v8i16 form: See the comment for ROTHM v8i16. The difference here is
2180// that the immediate can be complemented, so that the user doesn't have to
2181// worry about it.
2182def ROTHMIv8i16:
2183 RI7Form<0b10111110000, (outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val),
2184 "rothmi\t$rT, $rA, $val", RotateShift,
2185 [(set (v8i16 VECREG:$rT),
2186 (SPUvec_srl_v8i16 (v8i16 VECREG:$rA), (i32 imm:$val)))]>;
2187
2188def: Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), (i16 imm:$val)),
2189 (ROTHMIv8i16 VECREG:$rA, imm:$val)>;
2190
2191def ROTHMIr16:
2192 RI7Form<0b10111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm:$val),
2193 "rothmi\t$rT, $rA, $val", RotateShift,
2194 [(set R16C:$rT, (srl R16C:$rA, (i32 uimm7:$val)))]>;
2195
2196def: Pat<(srl R16C:$rA, (i16 uimm7:$val)),
2197 (ROTHMIr16 R16C:$rA, uimm7:$val)>;
2198
2199// ROTM v4i32 form: See the ROTHM v8i16 comments.
2200def ROTMv4i32:
2201 RRForm<0b10011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2202 "rotm\t$rT, $rA, $rB", RotateShift,
2203 [/* see patterns below - $rB must be negated */]>;
2204
2205def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, R32C:$rB),
2206 (ROTMv4i32 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
2207
2208def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, R16C:$rB),
2209 (ROTMv4i32 VECREG:$rA,
2210 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2211
2212def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, /* R8C */ R16C:$rB),
2213 (ROTMv4i32 VECREG:$rA,
2214 (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /*)*/, 0))>;
2215
2216def ROTMr32:
2217 RRForm<0b10011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
2218 "rotm\t$rT, $rA, $rB", RotateShift,
2219 [/* see patterns below - $rB must be negated */]>;
2220
2221def : Pat<(srl R32C:$rA, R32C:$rB),
2222 (ROTMr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>;
2223
2224def : Pat<(srl R32C:$rA, R16C:$rB),
2225 (ROTMr32 R32C:$rA,
2226 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2227
2228// ROTMI v4i32 form: See the comment for ROTHM v8i16.
2229def ROTMIv4i32:
2230 RI7Form<0b10011110000, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val),
2231 "rotmi\t$rT, $rA, $val", RotateShift,
2232 [(set (v4i32 VECREG:$rT),
2233 (SPUvec_srl_v4i32 VECREG:$rA, (i32 uimm7:$val)))]>;
2234
2235def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, (i16 uimm7:$val)),
2236 (ROTMIv4i32 VECREG:$rA, uimm7:$val)>;
2237
2238// ROTMI r32 form: know how to complement the immediate value.
2239def ROTMIr32:
2240 RI7Form<0b10011110000, (outs R32C:$rT), (ins R32C:$rA, rotNeg7imm:$val),
2241 "rotmi\t$rT, $rA, $val", RotateShift,
2242 [(set R32C:$rT, (srl R32C:$rA, (i32 uimm7:$val)))]>;
2243
2244def : Pat<(srl R32C:$rA, (i16 imm:$val)),
2245 (ROTMIr32 R32C:$rA, uimm7:$val)>;
2246
2247// ROTQMBYvec: This is a vector form merely so that when used in an
2248// instruction pattern, type checking will succeed. This instruction assumes
2249// that the user knew to complement $rB.
2250def ROTQMBYvec:
2251 RRForm<0b10111011100, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2252 "rotqmby\t$rT, $rA, $rB", RotateShift,
2253 [(set (v16i8 VECREG:$rT),
2254 (SPUrotbytes_right_zfill (v16i8 VECREG:$rA), R32C:$rB))]>;
2255
2256def ROTQMBYIvec:
2257 RI7Form<0b10111111100, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val),
2258 "rotqmbyi\t$rT, $rA, $val", RotateShift,
2259 [(set (v16i8 VECREG:$rT),
2260 (SPUrotbytes_right_zfill (v16i8 VECREG:$rA), (i32 uimm7:$val)))]>;
2261
2262def : Pat<(SPUrotbytes_right_zfill VECREG:$rA, (i16 uimm7:$val)),
2263 (ROTQMBYIvec VECREG:$rA, uimm7:$val)>;
2264
2265def ROTQMBYBIvec:
2266 RRForm<0b10110011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2267 "rotqmbybi\t$rT, $rA, $rB", RotateShift,
2268 [/* intrinsic */]>;
2269
2270def ROTQMBIvec:
2271 RRForm<0b10011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2272 "rotqmbi\t$rT, $rA, $rB", RotateShift,
2273 [/* intrinsic */]>;
2274
2275def ROTQMBIIvec:
2276 RI7Form<0b10011111100, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val),
2277 "rotqmbii\t$rT, $rA, $val", RotateShift,
2278 [/* intrinsic */]>;
2279
2280def ROTMAHv8i16:
2281 RRForm<0b01111010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2282 "rotmah\t$rT, $rA, $rB", RotateShift,
2283 [/* see patterns below - $rB must be negated */]>;
2284
2285def : Pat<(SPUvec_sra_v8i16 VECREG:$rA, R32C:$rB),
2286 (ROTMAHv8i16 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
2287
2288def : Pat<(SPUvec_sra_v8i16 VECREG:$rA, R16C:$rB),
2289 (ROTMAHv8i16 VECREG:$rA,
2290 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2291
2292def ROTMAHr16:
2293 RRForm<0b01111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB),
2294 "rotmah\t$rT, $rA, $rB", RotateShift,
2295 [/* see patterns below - $rB must be negated */]>;
2296
2297def : Pat<(sra R16C:$rA, R32C:$rB),
2298 (ROTMAHr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>;
2299
2300def : Pat<(sra R16C:$rA, R16C:$rB),
2301 (ROTMAHr16 R16C:$rA,
2302 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2303
2304def ROTMAHIv8i16:
2305 RRForm<0b01111110000, (outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val),
2306 "rotmahi\t$rT, $rA, $val", RotateShift,
2307 [(set (v8i16 VECREG:$rT),
2308 (SPUvec_sra_v8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val)))]>;
2309
2310def : Pat<(SPUvec_sra_v8i16 (v8i16 VECREG:$rA), (i16 uimm7:$val)),
2311 (ROTMAHIv8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val))>;
2312
2313def ROTMAHIr16:
2314 RRForm<0b01111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm_i16:$val),
2315 "rotmahi\t$rT, $rA, $val", RotateShift,
2316 [(set R16C:$rT, (sra R16C:$rA, (i16 uimm7:$val)))]>;
2317
2318def : Pat<(sra R16C:$rA, (i32 imm:$val)),
2319 (ROTMAHIr16 R16C:$rA, uimm7:$val)>;
2320
2321def ROTMAv4i32:
2322 RRForm<0b01011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
2323 "rotma\t$rT, $rA, $rB", RotateShift,
2324 [/* see patterns below - $rB must be negated */]>;
2325
2326def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, R32C:$rB),
2327 (ROTMAv4i32 (v4i32 VECREG:$rA), (SFIr32 R32C:$rB, 0))>;
2328
2329def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, R16C:$rB),
2330 (ROTMAv4i32 (v4i32 VECREG:$rA),
2331 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2332
2333def ROTMAr32:
2334 RRForm<0b01011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
2335 "rotma\t$rT, $rA, $rB", RotateShift,
2336 [/* see patterns below - $rB must be negated */]>;
2337
2338def : Pat<(sra R32C:$rA, R32C:$rB),
2339 (ROTMAr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>;
2340
2341def : Pat<(sra R32C:$rA, R16C:$rB),
2342 (ROTMAr32 R32C:$rA,
2343 (SFIr32 (XSHWr16 R16C:$rB), 0))>;
2344
2345def ROTMAIv4i32:
2346 RRForm<0b01011110000, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val),
2347 "rotmai\t$rT, $rA, $val", RotateShift,
2348 [(set (v4i32 VECREG:$rT),
2349 (SPUvec_sra_v4i32 VECREG:$rA, (i32 uimm7:$val)))]>;
2350
2351def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, (i16 uimm7:$val)),
2352 (ROTMAIv4i32 VECREG:$rA, uimm7:$val)>;
2353
2354def ROTMAIr32:
2355 RRForm<0b01011110000, (outs R32C:$rT), (ins R32C:$rA, rotNeg7imm:$val),
2356 "rotmai\t$rT, $rA, $val", RotateShift,
2357 [(set R32C:$rT, (sra R32C:$rA, (i32 uimm7:$val)))]>;
2358
2359def : Pat<(sra R32C:$rA, (i16 uimm7:$val)),
2360 (ROTMAIr32 R32C:$rA, uimm7:$val)>;
2361
2362//===----------------------------------------------------------------------===//
2363// Branch and conditionals:
2364//===----------------------------------------------------------------------===//
2365
2366let isTerminator = 1, isBarrier = 1 in {
2367 // Halt If Equal (r32 preferred slot only, no vector form)
2368 def HEQr32:
2369 RRForm_3<0b00011011110, (outs), (ins R32C:$rA, R32C:$rB),
2370 "heq\t$rA, $rB", BranchResolv,
2371 [/* no pattern to match */]>;
2372
2373 def HEQIr32 :
2374 RI10Form_2<0b11111110, (outs), (ins R32C:$rA, s10imm:$val),
2375 "heqi\t$rA, $val", BranchResolv,
2376 [/* no pattern to match */]>;
2377
2378 // HGT/HGTI: These instructions use signed arithmetic for the comparison,
2379 // contrasting with HLGT/HLGTI, which use unsigned comparison:
2380 def HGTr32:
2381 RRForm_3<0b00011010010, (outs), (ins R32C:$rA, R32C:$rB),
2382 "hgt\t$rA, $rB", BranchResolv,
2383 [/* no pattern to match */]>;
2384
2385 def HGTIr32:
2386 RI10Form_2<0b11110010, (outs), (ins R32C:$rA, s10imm:$val),
2387 "hgti\t$rA, $val", BranchResolv,
2388 [/* no pattern to match */]>;
2389
2390 def HLGTr32:
2391 RRForm_3<0b00011011010, (outs), (ins R32C:$rA, R32C:$rB),
2392 "hlgt\t$rA, $rB", BranchResolv,
2393 [/* no pattern to match */]>;
2394
2395 def HLGTIr32:
2396 RI10Form_2<0b11111010, (outs), (ins R32C:$rA, s10imm:$val),
2397 "hlgti\t$rA, $val", BranchResolv,
2398 [/* no pattern to match */]>;
2399}
2400
2401// Comparison operators:
2402
2403def CEQBv16i8:
2404 RRForm<0b00001011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2405 "ceqb\t$rT, $rA, $rB", ByteOp,
2406 [/* no pattern to match: intrinsic */]>;
2407
2408def CEQBIv16i8:
2409 RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm:$val),
2410 "ceqbi\t$rT, $rA, $val", ByteOp,
2411 [/* no pattern to match: intrinsic */]>;
2412
2413def CEQHr16:
2414 RRForm<0b00010011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
2415 "ceqh\t$rT, $rA, $rB", ByteOp,
2416 [/* no pattern to match */]>;
2417
2418def CEQHv8i16:
2419 RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2420 "ceqh\t$rT, $rA, $rB", ByteOp,
2421 [/* no pattern to match: intrinsic */]>;
2422
2423def CEQHIr16:
2424 RI10Form<0b10111110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val),
2425 "ceqhi\t$rT, $rA, $val", ByteOp,
2426 [/* no pattern to match: intrinsic */]>;
2427
2428def CEQHIv8i16:
2429 RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
2430 "ceqhi\t$rT, $rA, $val", ByteOp,
2431 [/* no pattern to match: intrinsic */]>;
2432
2433def CEQr32:
2434 RRForm<0b00000011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
2435 "ceq\t$rT, $rA, $rB", ByteOp,
2436 [/* no pattern to match: intrinsic */]>;
2437
2438def CEQv4i32:
2439 RRForm<0b00000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2440 "ceq\t$rT, $rA, $rB", ByteOp,
2441 [/* no pattern to match: intrinsic */]>;
2442
2443def CEQIr32:
2444 RI10Form<0b00111110, (outs R32C:$rT), (ins R32C:$rA, s10imm:$val),
2445 "ceqi\t$rT, $rA, $val", ByteOp,
2446 [/* no pattern to match: intrinsic */]>;
2447
2448def CEQIv4i32:
2449 RI10Form<0b00111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
2450 "ceqi\t$rT, $rA, $val", ByteOp,
2451 [/* no pattern to match: intrinsic */]>;
2452
2453let isCall = 1,
2454 // All calls clobber the non-callee-saved registers:
2455 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R9,
2456 R10,R11,R12,R13,R14,R15,R16,R17,R18,R19,
2457 R20,R21,R22,R23,R24,R25,R26,R27,R28,R29,
2458 R30,R31,R32,R33,R34,R35,R36,R37,R38,R39,
2459 R40,R41,R42,R43,R44,R45,R46,R47,R48,R49,
2460 R50,R51,R52,R53,R54,R55,R56,R57,R58,R59,
2461 R60,R61,R62,R63,R64,R65,R66,R67,R68,R69,
2462 R70,R71,R72,R73,R74,R75,R76,R77,R78,R79],
2463 // All of these instructions use $lr (aka $0)
2464 Uses = [R0] in {
2465 // Branch relative and set link: Used if we actually know that the target
2466 // is within [-32768, 32767] bytes of the target
2467 def BRSL:
2468 BranchSetLink<0b011001100, (outs), (ins relcalltarget:$func, variable_ops),
2469 "brsl\t$$lr, $func",
2470 [(SPUcall (SPUpcrel tglobaladdr:$func, 0))]>;
2471
2472 // Branch absolute and set link: Used if we actually know that the target
2473 // is an absolute address
2474 def BRASL:
2475 BranchSetLink<0b011001100, (outs), (ins calltarget:$func, variable_ops),
2476 "brasl\t$$lr, $func",
2477 [(SPUcall tglobaladdr:$func)]>;
2478
2479 // Branch indirect and set link if external data. These instructions are not
2480 // actually generated, matched by an intrinsic:
2481 def BISLED_00: BISLEDForm<0b11, "bisled\t$$lr, $func", [/* empty pattern */]>;
2482 def BISLED_E0: BISLEDForm<0b10, "bisled\t$$lr, $func", [/* empty pattern */]>;
2483 def BISLED_0D: BISLEDForm<0b01, "bisled\t$$lr, $func", [/* empty pattern */]>;
2484 def BISLED_ED: BISLEDForm<0b00, "bisled\t$$lr, $func", [/* empty pattern */]>;
2485
2486 // Branch indirect and set link. This is the "X-form" address version of a
2487 // function call
2488 def BISL:
2489 BIForm<0b10010101100, "bisl\t$$lr, $func", [(SPUcall R32C:$func)]>;
2490}
2491
2492// Unconditional branches:
2493let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
2494 def BR :
2495 UncondBranch<0b001001100, (outs), (ins brtarget:$dest),
2496 "br\t$dest",
2497 [(br bb:$dest)]>;
2498
2499 // Unconditional, absolute address branch
2500 def BRA:
2501 UncondBranch<0b001100000, (outs), (ins brtarget:$dest),
2502 "bra\t$dest",
2503 [/* no pattern */]>;
2504
2505 // Indirect branch
2506 def BI:
2507 BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>;
2508
2509 // Various branches:
2510 def BRNZ:
2511 RI16Form<0b010000100, (outs), (ins R32C:$rCond, brtarget:$dest),
2512 "brnz\t$rCond,$dest",
2513 BranchResolv,
2514 [(brcond R32C:$rCond, bb:$dest)]>;
2515
2516 def BRZ:
2517 RI16Form<0b000000100, (outs), (ins R32C:$rT, brtarget:$dest),
2518 "brz\t$rT,$dest",
2519 BranchResolv,
2520 [/* no pattern */]>;
2521
2522 def BRHNZ:
2523 RI16Form<0b011000100, (outs), (ins R16C:$rCond, brtarget:$dest),
2524 "brhnz\t$rCond,$dest",
2525 BranchResolv,
2526 [(brcond R16C:$rCond, bb:$dest)]>;
2527
2528 def BRHZ:
2529 RI16Form<0b001000100, (outs), (ins R16C:$rT, brtarget:$dest),
2530 "brhz\t$rT,$dest",
2531 BranchResolv,
2532 [/* no pattern */]>;
2533
2534/*
2535 def BINZ:
2536 BICondForm<0b10010100100, "binz\t$rA, $func",
2537 [(SPUbinz R32C:$rA, R32C:$func)]>;
2538
2539 def BIZ:
2540 BICondForm<0b00010100100, "biz\t$rA, $func",
2541 [(SPUbiz R32C:$rA, R32C:$func)]>;
2542*/
2543}
2544
2545def : Pat<(brcond (i16 (seteq R16C:$rA, 0)), bb:$dest),
2546 (BRHZ R16C:$rA, bb:$dest)>;
2547def : Pat<(brcond (i16 (setne R16C:$rA, 0)), bb:$dest),
2548 (BRHNZ R16C:$rA, bb:$dest)>;
2549
2550def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest),
2551 (BRZ R32C:$rA, bb:$dest)>;
2552def : Pat<(brcond (i32 (setne R32C:$rA, 0)), bb:$dest),
2553 (BRZ R32C:$rA, bb:$dest)>;
2554
2555let isTerminator = 1, isBarrier = 1 in {
2556 let isReturn = 1 in {
2557 def RET:
2558 RETForm<"bi\t$$lr", [(retflag)]>;
2559 }
2560}
2561
2562//===----------------------------------------------------------------------===//
2563// Various brcond predicates:
2564//===----------------------------------------------------------------------===//
2565/*
2566def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest),
2567 (BRZ R32C:$rA, bb:$dest)>;
2568
2569def : Pat<(brcond (i32 (seteq R32C:$rA, R32C:$rB)), bb:$dest),
2570 (BRNZ (CEQr32 R32C:$rA, R32C:$rB), bb:$dest)>;
2571
2572def : Pat<(brcond (i16 (seteq R16C:$rA, i16ImmSExt10:$val)), bb:$dest),
2573 (BRHNZ (CEQHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>;
2574
2575def : Pat<(brcond (i16 (seteq R16C:$rA, R16C:$rB)), bb:$dest),
2576 (BRHNZ (CEQHr16 R16C:$rA, R16C:$rB), bb:$dest)>;
2577*/
2578
2579//===----------------------------------------------------------------------===//
2580// Single precision floating point instructions
2581//===----------------------------------------------------------------------===//
2582
2583def FAv4f32:
2584 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2585 "fa\t$rT, $rA, $rB", SPrecFP,
2586 [(set (v4f32 VECREG:$rT), (fadd (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)))]>;
2587
2588def FAf32 :
2589 RRForm<0b00100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
2590 "fa\t$rT, $rA, $rB", SPrecFP,
2591 [(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>;
2592
2593def FSv4f32:
2594 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2595 "fs\t$rT, $rA, $rB", SPrecFP,
2596 [(set (v4f32 VECREG:$rT), (fsub (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)))]>;
2597
2598def FSf32 :
2599 RRForm<0b10100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
2600 "fs\t$rT, $rA, $rB", SPrecFP,
2601 [(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>;
2602
2603// Floating point reciprocal estimate
2604def FREv4f32 :
2605 RRForm_1<0b00011101100, (outs VECREG:$rT), (ins VECREG:$rA),
2606 "frest\t$rT, $rA", SPrecFP,
2607 [(set (v4f32 VECREG:$rT), (SPUreciprocalEst (v4f32 VECREG:$rA)))]>;
2608
2609def FREf32 :
2610 RRForm_1<0b00011101100, (outs R32FP:$rT), (ins R32FP:$rA),
2611 "frest\t$rT, $rA", SPrecFP,
2612 [(set R32FP:$rT, (SPUreciprocalEst R32FP:$rA))]>;
2613
2614// Floating point interpolate (used in conjunction with reciprocal estimate)
2615def FIv4f32 :
2616 RRForm<0b00101011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2617 "fi\t$rT, $rA, $rB", SPrecFP,
2618 [(set (v4f32 VECREG:$rT), (SPUinterpolate (v4f32 VECREG:$rA),
2619 (v4f32 VECREG:$rB)))]>;
2620
2621def FIf32 :
2622 RRForm<0b00101011110, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
2623 "fi\t$rT, $rA, $rB", SPrecFP,
2624 [(set R32FP:$rT, (SPUinterpolate R32FP:$rA, R32FP:$rB))]>;
2625
2626// Floating Compare Equal
2627def FCEQf32 :
2628 RRForm<0b01000011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB),
2629 "fceq\t$rT, $rA, $rB", SPrecFP,
2630 [(set R32C:$rT, (setoeq R32FP:$rA, R32FP:$rB))]>;
2631
2632def FCMEQf32 :
2633 RRForm<0b01010011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB),
2634 "fcmeq\t$rT, $rA, $rB", SPrecFP,
2635 [(set R32C:$rT, (setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>;
2636
2637def FCGTf32 :
2638 RRForm<0b01000011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB),
2639 "fcgt\t$rT, $rA, $rB", SPrecFP,
2640 [(set R32C:$rT, (setogt R32FP:$rA, R32FP:$rB))]>;
2641
2642def FCMGTf32 :
2643 RRForm<0b01010011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB),
2644 "fcmgt\t$rT, $rA, $rB", SPrecFP,
2645 [(set R32C:$rT, (setogt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>;
2646
2647// FP Status and Control Register Write
2648// Why isn't rT a don't care in the ISA?
2649// Should we create a special RRForm_3 for this guy and zero out the rT?
2650def FSCRWf32 :
2651 RRForm_1<0b01011101110, (outs R32FP:$rT), (ins R32FP:$rA),
2652 "fscrwr\t$rA", SPrecFP,
2653 [/* This instruction requires an intrinsic. Note: rT is unused. */]>;
2654
2655// FP Status and Control Register Read
2656def FSCRRf32 :
2657 RRForm_2<0b01011101110, (outs R32FP:$rT), (ins),
2658 "fscrrd\t$rT", SPrecFP,
2659 [/* This instruction requires an intrinsic */]>;
2660
2661// llvm instruction space
2662// How do these map onto cell instructions?
2663// fdiv rA rB
2664// frest rC rB # c = 1/b (both lines)
2665// fi rC rB rC
2666// fm rD rA rC # d = a * 1/b
2667// fnms rB rD rB rA # b = - (d * b - a) --should == 0 in a perfect world
2668// fma rB rB rC rD # b = b * c + d
2669// = -(d *b -a) * c + d
2670// = a * c - c ( a *b *c - a)
2671
2672// fcopysign (???)
2673
2674// Library calls:
2675// These llvm instructions will actually map to library calls.
2676// All that's needed, then, is to check that the appropriate library is
2677// imported and do a brsl to the proper function name.
2678// frem # fmod(x, y): x - (x/y) * y
2679// (Note: fmod(double, double), fmodf(float,float)
2680// fsqrt?
2681// fsin?
2682// fcos?
2683// Unimplemented SPU instruction space
2684// floating reciprocal absolute square root estimate (frsqest)
2685
2686// The following are probably just intrinsics
2687// status and control register write
2688// status and control register read
2689
2690//--------------------------------------
2691// Floating point multiply instructions
2692//--------------------------------------
2693
2694def FMv4f32:
2695 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2696 "fm\t$rT, $rA, $rB", SPrecFP,
2697 [(set (v4f32 VECREG:$rT), (fmul (v4f32 VECREG:$rA),
2698 (v4f32 VECREG:$rB)))]>;
2699
2700def FMf32 :
2701 RRForm<0b01100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
2702 "fm\t$rT, $rA, $rB", SPrecFP,
2703 [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>;
2704
2705// Floating point multiply and add
2706// e.g. d = c + (a * b)
2707def FMAv4f32:
2708 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2709 "fma\t$rT, $rA, $rB, $rC", SPrecFP,
2710 [(set (v4f32 VECREG:$rT),
2711 (fadd (v4f32 VECREG:$rC),
2712 (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>;
2713
2714def FMAf32:
2715 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
2716 "fma\t$rT, $rA, $rB, $rC", SPrecFP,
2717 [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
2718
2719// FP multiply and subtract
2720// Subtracts value in rC from product
2721// res = a * b - c
2722def FMSv4f32 :
2723 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2724 "fms\t$rT, $rA, $rB, $rC", SPrecFP,
2725 [(set (v4f32 VECREG:$rT),
2726 (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)),
2727 (v4f32 VECREG:$rC)))]>;
2728
2729def FMSf32 :
2730 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
2731 "fms\t$rT, $rA, $rB, $rC", SPrecFP,
2732 [(set R32FP:$rT,
2733 (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>;
2734
2735// Floating Negative Mulitply and Subtract
2736// Subtracts product from value in rC
2737// res = fneg(fms a b c)
2738// = - (a * b - c)
2739// = c - a * b
2740// NOTE: subtraction order
2741// fsub a b = a - b
2742// fs a b = b - a?
2743def FNMSf32 :
2744 RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC),
2745 "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
2746 [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>;
2747
2748def FNMSv4f32 :
2749 RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2750 "fnms\t$rT, $rA, $rB, $rC", SPrecFP,
2751 [(set (v4f32 VECREG:$rT),
2752 (fsub (v4f32 VECREG:$rC),
2753 (fmul (v4f32 VECREG:$rA),
2754 (v4f32 VECREG:$rB))))]>;
2755
2756//--------------------------------------
2757// Floating Point Conversions
2758// Signed conversions:
2759def CSiFv4f32:
2760 CVTIntFPForm<0b0101101110, (outs VECREG:$rT), (ins VECREG:$rA),
2761 "csflt\t$rT, $rA, 0", SPrecFP,
2762 [(set (v4f32 VECREG:$rT), (sint_to_fp (v4i32 VECREG:$rA)))]>;
2763
2764// Convert signed integer to floating point
2765def CSiFf32 :
2766 CVTIntFPForm<0b0101101110, (outs R32FP:$rT), (ins R32C:$rA),
2767 "csflt\t$rT, $rA, 0", SPrecFP,
2768 [(set R32FP:$rT, (sint_to_fp R32C:$rA))]>;
2769
2770// Convert unsigned into to float
2771def CUiFv4f32 :
2772 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA),
2773 "cuflt\t$rT, $rA, 0", SPrecFP,
2774 [(set (v4f32 VECREG:$rT), (uint_to_fp (v4i32 VECREG:$rA)))]>;
2775
2776def CUiFf32 :
2777 CVTIntFPForm<0b1101101110, (outs R32FP:$rT), (ins R32C:$rA),
2778 "cuflt\t$rT, $rA, 0", SPrecFP,
2779 [(set R32FP:$rT, (uint_to_fp R32C:$rA))]>;
2780
2781// Convert float to unsigned int
2782// Assume that scale = 0
2783
2784def CFUiv4f32 :
2785 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA),
2786 "cfltu\t$rT, $rA, 0", SPrecFP,
2787 [(set (v4i32 VECREG:$rT), (fp_to_uint (v4f32 VECREG:$rA)))]>;
2788
2789def CFUif32 :
2790 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA),
2791 "cfltu\t$rT, $rA, 0", SPrecFP,
2792 [(set R32C:$rT, (fp_to_uint R32FP:$rA))]>;
2793
2794// Convert float to signed int
2795// Assume that scale = 0
2796
2797def CFSiv4f32 :
2798 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA),
2799 "cflts\t$rT, $rA, 0", SPrecFP,
2800 [(set (v4i32 VECREG:$rT), (fp_to_sint (v4f32 VECREG:$rA)))]>;
2801
2802def CFSif32 :
2803 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA),
2804 "cflts\t$rT, $rA, 0", SPrecFP,
2805 [(set R32C:$rT, (fp_to_sint R32FP:$rA))]>;
2806
2807//===----------------------------------------------------------------------==//
2808// Single<->Double precision conversions
2809//===----------------------------------------------------------------------==//
2810
2811// NOTE: We use "vec" name suffix here to avoid confusion (e.g. input is a
2812// v4f32, output is v2f64--which goes in the name?)
2813
2814// Floating point extend single to double
2815// NOTE: Not sure if passing in v4f32 to FESDvec is correct since it
2816// operates on two double-word slots (i.e. 1st and 3rd fp numbers
2817// are ignored).
2818def FESDvec :
2819 RRForm_1<0b00011101110, (outs VECREG:$rT), (ins VECREG:$rA),
2820 "fesd\t$rT, $rA", SPrecFP,
2821 [(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))]>;
2822
2823def FESDf32 :
2824 RRForm_1<0b00011101110, (outs R64FP:$rT), (ins R32FP:$rA),
2825 "fesd\t$rT, $rA", SPrecFP,
2826 [(set R64FP:$rT, (fextend R32FP:$rA))]>;
2827
2828// Floating point round double to single
2829//def FRDSvec :
2830// RRForm_1<0b10011101110, (outs VECREG:$rT), (ins VECREG:$rA),
2831// "frds\t$rT, $rA,", SPrecFP,
2832// [(set (v4f32 R32FP:$rT), (fround (v2f64 R64FP:$rA)))]>;
2833
2834def FRDSf64 :
2835 RRForm_1<0b10011101110, (outs R32FP:$rT), (ins R64FP:$rA),
2836 "frds\t$rT, $rA", SPrecFP,
2837 [(set R32FP:$rT, (fround R64FP:$rA))]>;
2838
2839//ToDo include anyextend?
2840
2841//===----------------------------------------------------------------------==//
2842// Double precision floating point instructions
2843//===----------------------------------------------------------------------==//
2844def FAf64 :
2845 RRForm<0b00110011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB),
2846 "dfa\t$rT, $rA, $rB", DPrecFP,
2847 [(set R64FP:$rT, (fadd R64FP:$rA, R64FP:$rB))]>;
2848
2849def FAv2f64 :
2850 RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2851 "dfa\t$rT, $rA, $rB", DPrecFP,
2852 [(set (v2f64 VECREG:$rT), (fadd (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>;
2853
2854def FSf64 :
2855 RRForm<0b10100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB),
2856 "dfs\t$rT, $rA, $rB", DPrecFP,
2857 [(set R64FP:$rT, (fsub R64FP:$rA, R64FP:$rB))]>;
2858
2859def FSv2f64 :
2860 RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2861 "dfs\t$rT, $rA, $rB", DPrecFP,
2862 [(set (v2f64 VECREG:$rT),
2863 (fsub (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>;
2864
2865def FMf64 :
2866 RRForm<0b01100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB),
2867 "dfm\t$rT, $rA, $rB", DPrecFP,
2868 [(set R64FP:$rT, (fmul R64FP:$rA, R64FP:$rB))]>;
2869
2870def FMv2f64:
2871 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
2872 "dfm\t$rT, $rA, $rB", DPrecFP,
2873 [(set (v2f64 VECREG:$rT),
2874 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>;
2875
2876def FMAf64:
2877 RRForm<0b00111010110, (outs R64FP:$rT),
2878 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
2879 "dfma\t$rT, $rA, $rB", DPrecFP,
2880 [(set R64FP:$rT, (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>,
2881 RegConstraint<"$rC = $rT">,
2882 NoEncode<"$rC">;
2883
2884def FMAv2f64:
2885 RRForm<0b00111010110, (outs VECREG:$rT),
2886 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2887 "dfma\t$rT, $rA, $rB", DPrecFP,
2888 [(set (v2f64 VECREG:$rT),
2889 (fadd (v2f64 VECREG:$rC),
2890 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB))))]>,
2891 RegConstraint<"$rC = $rT">,
2892 NoEncode<"$rC">;
2893
2894def FMSf64 :
2895 RRForm<0b10111010110, (outs R64FP:$rT),
2896 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
2897 "dfms\t$rT, $rA, $rB", DPrecFP,
2898 [(set R64FP:$rT, (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))]>,
2899 RegConstraint<"$rC = $rT">,
2900 NoEncode<"$rC">;
2901
2902def FMSv2f64 :
2903 RRForm<0b10111010110, (outs VECREG:$rT),
2904 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2905 "dfms\t$rT, $rA, $rB", DPrecFP,
2906 [(set (v2f64 VECREG:$rT),
2907 (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
2908 (v2f64 VECREG:$rC)))]>;
2909
2910// FNMS: - (a * b - c)
2911// - (a * b) + c => c - (a * b)
2912def FNMSf64 :
2913 RRForm<0b01111010110, (outs R64FP:$rT),
2914 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
2915 "dfnms\t$rT, $rA, $rB", DPrecFP,
2916 [(set R64FP:$rT, (fsub R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>,
2917 RegConstraint<"$rC = $rT">,
2918 NoEncode<"$rC">;
2919
2920def : Pat<(fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)),
2921 (FNMSf64 R64FP:$rA, R64FP:$rB, R64FP:$rC)>;
2922
2923def FNMSv2f64 :
2924 RRForm<0b01111010110, (outs VECREG:$rT),
2925 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2926 "dfnms\t$rT, $rA, $rB", DPrecFP,
2927 [(set (v2f64 VECREG:$rT),
2928 (fsub (v2f64 VECREG:$rC),
2929 (fmul (v2f64 VECREG:$rA),
2930 (v2f64 VECREG:$rB))))]>,
2931 RegConstraint<"$rC = $rT">,
2932 NoEncode<"$rC">;
2933
2934def : Pat<(fneg (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
2935 (v2f64 VECREG:$rC))),
2936 (FNMSv2f64 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
2937
2938// - (a * b + c)
2939// - (a * b) - c
2940def FNMAf64 :
2941 RRForm<0b11111010110, (outs R64FP:$rT),
2942 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
2943 "dfnma\t$rT, $rA, $rB", DPrecFP,
2944 [(set R64FP:$rT, (fneg (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB))))]>,
2945 RegConstraint<"$rC = $rT">,
2946 NoEncode<"$rC">;
2947
2948def FNMAv2f64 :
2949 RRForm<0b11111010110, (outs VECREG:$rT),
2950 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
2951 "dfnma\t$rT, $rA, $rB", DPrecFP,
2952 [(set (v2f64 VECREG:$rT),
2953 (fneg (fadd (v2f64 VECREG:$rC),
2954 (fmul (v2f64 VECREG:$rA),
2955 (v2f64 VECREG:$rB)))))]>,
2956 RegConstraint<"$rC = $rT">,
2957 NoEncode<"$rC">;
2958
2959//===----------------------------------------------------------------------==//
2960// Floating point negation and absolute value
2961//===----------------------------------------------------------------------==//
2962
2963def : Pat<(fneg (v4f32 VECREG:$rA)),
2964 (XORfnegvec (v4f32 VECREG:$rA),
2965 (v4f32 (ILHUv4i32 0x8000)))>;
2966
2967def : Pat<(fneg R32FP:$rA),
2968 (XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>;
2969
2970def : Pat<(fneg (v2f64 VECREG:$rA)),
2971 (XORfnegvec (v2f64 VECREG:$rA),
2972 (v2f64 (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80)))>;
2973
2974def : Pat<(fneg R64FP:$rA),
2975 (XORfneg64 R64FP:$rA,
2976 (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80))>;
2977
2978// Floating point absolute value
2979
2980def : Pat<(fabs R32FP:$rA),
2981 (ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>;
2982
2983def : Pat<(fabs (v4f32 VECREG:$rA)),
2984 (ANDfabsvec (v4f32 VECREG:$rA),
2985 (v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
2986
2987def : Pat<(fabs R64FP:$rA),
2988 (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>;
2989
2990def : Pat<(fabs (v2f64 VECREG:$rA)),
2991 (ANDfabsvec (v2f64 VECREG:$rA),
2992 (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
2993
2994//===----------------------------------------------------------------------===//
2995// Execution, Load NOP (execute NOPs belong in even pipeline, load NOPs belong
2996// in the odd pipeline)
2997//===----------------------------------------------------------------------===//
2998
2999def ENOP : I<(outs), (ins), "enop", ExecNOP> {
3000 let Pattern = [];
3001
3002 let Inst{0-10} = 0b10000000010;
3003 let Inst{11-17} = 0;
3004 let Inst{18-24} = 0;
3005 let Inst{25-31} = 0;
3006}
3007
3008def LNOP : I<(outs), (ins), "lnop", LoadNOP> {
3009 let Pattern = [];
3010
3011 let Inst{0-10} = 0b10000000000;
3012 let Inst{11-17} = 0;
3013 let Inst{18-24} = 0;
3014 let Inst{25-31} = 0;
3015}
3016
3017//===----------------------------------------------------------------------===//
3018// Bit conversions (type conversions between vector/packed types)
3019// NOTE: Promotions are handled using the XS* instructions. Truncation
3020// is not handled.
3021//===----------------------------------------------------------------------===//
3022def : Pat<(v16i8 (bitconvert (v8i16 VECREG:$src))), (v16i8 VECREG:$src)>;
3023def : Pat<(v16i8 (bitconvert (v4i32 VECREG:$src))), (v16i8 VECREG:$src)>;
3024def : Pat<(v16i8 (bitconvert (v2i64 VECREG:$src))), (v16i8 VECREG:$src)>;
3025def : Pat<(v16i8 (bitconvert (v4f32 VECREG:$src))), (v16i8 VECREG:$src)>;
3026def : Pat<(v16i8 (bitconvert (v2f64 VECREG:$src))), (v16i8 VECREG:$src)>;
3027
3028def : Pat<(v8i16 (bitconvert (v16i8 VECREG:$src))), (v8i16 VECREG:$src)>;
3029def : Pat<(v8i16 (bitconvert (v4i32 VECREG:$src))), (v8i16 VECREG:$src)>;
3030def : Pat<(v8i16 (bitconvert (v2i64 VECREG:$src))), (v8i16 VECREG:$src)>;
3031def : Pat<(v8i16 (bitconvert (v4f32 VECREG:$src))), (v8i16 VECREG:$src)>;
3032def : Pat<(v8i16 (bitconvert (v2f64 VECREG:$src))), (v8i16 VECREG:$src)>;
3033
3034def : Pat<(v4i32 (bitconvert (v16i8 VECREG:$src))), (v4i32 VECREG:$src)>;
3035def : Pat<(v4i32 (bitconvert (v8i16 VECREG:$src))), (v4i32 VECREG:$src)>;
3036def : Pat<(v4i32 (bitconvert (v2i64 VECREG:$src))), (v4i32 VECREG:$src)>;
3037def : Pat<(v4i32 (bitconvert (v4f32 VECREG:$src))), (v4i32 VECREG:$src)>;
3038def : Pat<(v4i32 (bitconvert (v2f64 VECREG:$src))), (v4i32 VECREG:$src)>;
3039
3040def : Pat<(v2i64 (bitconvert (v16i8 VECREG:$src))), (v2i64 VECREG:$src)>;
3041def : Pat<(v2i64 (bitconvert (v8i16 VECREG:$src))), (v2i64 VECREG:$src)>;
3042def : Pat<(v2i64 (bitconvert (v4i32 VECREG:$src))), (v2i64 VECREG:$src)>;
3043def : Pat<(v2i64 (bitconvert (v4f32 VECREG:$src))), (v2i64 VECREG:$src)>;
3044def : Pat<(v2i64 (bitconvert (v2f64 VECREG:$src))), (v2i64 VECREG:$src)>;
3045
3046def : Pat<(v4f32 (bitconvert (v16i8 VECREG:$src))), (v4f32 VECREG:$src)>;
3047def : Pat<(v4f32 (bitconvert (v8i16 VECREG:$src))), (v4f32 VECREG:$src)>;
3048def : Pat<(v4f32 (bitconvert (v2i64 VECREG:$src))), (v4f32 VECREG:$src)>;
3049def : Pat<(v4f32 (bitconvert (v4i32 VECREG:$src))), (v4f32 VECREG:$src)>;
3050def : Pat<(v4f32 (bitconvert (v2f64 VECREG:$src))), (v4f32 VECREG:$src)>;
3051
3052def : Pat<(v2f64 (bitconvert (v16i8 VECREG:$src))), (v2f64 VECREG:$src)>;
3053def : Pat<(v2f64 (bitconvert (v8i16 VECREG:$src))), (v2f64 VECREG:$src)>;
3054def : Pat<(v2f64 (bitconvert (v4i32 VECREG:$src))), (v2f64 VECREG:$src)>;
3055def : Pat<(v2f64 (bitconvert (v2i64 VECREG:$src))), (v2f64 VECREG:$src)>;
3056def : Pat<(v2f64 (bitconvert (v2f64 VECREG:$src))), (v2f64 VECREG:$src)>;
3057
3058def : Pat<(f32 (bitconvert (i32 R32C:$src))), (f32 R32FP:$src)>;
3059
3060//===----------------------------------------------------------------------===//
3061// Instruction patterns:
3062//===----------------------------------------------------------------------===//
3063
3064// General 32-bit constants:
3065def : Pat<(i32 imm:$imm),
3066 (IOHLr32 (ILHUr32 (HI16 imm:$imm)), (LO16 imm:$imm))>;
3067
3068// Single precision float constants:
3069def : Pat<(SPUFPconstant (f32 fpimm:$imm)),
3070 (IOHLf32 (ILHUf32 (HI16_f32 fpimm:$imm)), (LO16_f32 fpimm:$imm))>;
3071
3072// General constant 32-bit vectors
3073def : Pat<(v4i32 v4i32Imm:$imm),
3074 (IOHLvec (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))),
3075 (LO16_vec v4i32Imm:$imm))>;
3076
3077//===----------------------------------------------------------------------===//
3078// Call instruction patterns:
3079//===----------------------------------------------------------------------===//
3080// Return void
3081def : Pat<(ret),
3082 (RET)>;
3083
3084//===----------------------------------------------------------------------===//
3085// Zero/Any/Sign extensions
3086//===----------------------------------------------------------------------===//
3087
3088// zext 1->32: Zero extend i1 to i32
3089def : Pat<(SPUextract_i1_zext R32C:$rSrc),
3090 (ANDIr32 R32C:$rSrc, 0x1)>;
3091
3092// sext 8->32: Sign extend bytes to words
3093def : Pat<(sext_inreg R32C:$rSrc, i8),
3094 (XSHWr32 (XSBHr32 R32C:$rSrc))>;
3095
3096def : Pat<(SPUextract_i8_sext VECREG:$rSrc),
3097 (XSHWr32 (XSBHr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc),
3098 (v4i32 VECREG:$rSrc))))>;
3099
3100def : Pat<(SPUextract_i8_zext VECREG:$rSrc),
3101 (ANDIr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc), (v4i32 VECREG:$rSrc)),
3102 0xff)>;
3103
3104// zext 16->32: Zero extend halfwords to words (note that we have to juggle the
3105// 0xffff constant since it will not fit into an immediate.)
3106def : Pat<(i32 (zext R16C:$rSrc)),
3107 (AND2To4 R16C:$rSrc, (ILAr32 0xffff))>;
3108
3109def : Pat<(i32 (zext (and R16C:$rSrc, 0xf))),
3110 (ANDI2To4 R16C:$rSrc, 0xf)>;
3111
3112def : Pat<(i32 (zext (and R16C:$rSrc, 0xff))),
3113 (ANDI2To4 R16C:$rSrc, 0xff)>;
3114
3115def : Pat<(i32 (zext (and R16C:$rSrc, 0xfff))),
3116 (ANDI2To4 R16C:$rSrc, 0xfff)>;
3117
3118// anyext 16->32: Extend 16->32 bits, irrespective of sign
3119def : Pat<(i32 (anyext R16C:$rSrc)),
3120 (ORI2To4 R16C:$rSrc, 0)>;
3121
3122//===----------------------------------------------------------------------===//
3123// Address translation: SPU, like PPC, has to split addresses into high and
3124// low parts in order to load them into a register.
3125//===----------------------------------------------------------------------===//
3126
3127def : Pat<(SPUhi tglobaladdr:$in, 0), (ILHUhi tglobaladdr:$in)>;
3128def : Pat<(SPUlo tglobaladdr:$in, 0), (ILAlo tglobaladdr:$in)>;
3129def : Pat<(SPUdform tglobaladdr:$in, imm:$imm), (ILAlsa tglobaladdr:$in)>;
3130def : Pat<(SPUhi tconstpool:$in , 0), (ILHUhi tconstpool:$in)>;
3131def : Pat<(SPUlo tconstpool:$in , 0), (ILAlo tconstpool:$in)>;
3132def : Pat<(SPUdform tconstpool:$in, imm:$imm), (ILAlsa tconstpool:$in)>;
3133def : Pat<(SPUhi tjumptable:$in, 0), (ILHUhi tjumptable:$in)>;
3134def : Pat<(SPUlo tjumptable:$in, 0), (ILAlo tjumptable:$in)>;
3135def : Pat<(SPUdform tjumptable:$in, imm:$imm), (ILAlsa tjumptable:$in)>;
3136
3137// Force load of global address to a register. These forms show up in
3138// SPUISD::DFormAddr pseudo instructions:
3139/*
3140def : Pat<(add tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>;
3141def : Pat<(add tconstpool:$in, 0), (ILAlsa tglobaladdr:$in)>;
3142def : Pat<(add tjumptable:$in, 0), (ILAlsa tglobaladdr:$in)>;
3143 */
3144// Instrinsics:
3145include "CellSDKIntrinsics.td"