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