blob: 14bfd8cc18d522d395be5aa26af0b84e6c4b15d9 [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===-- AMDGPUInstructions.td - Common instruction defs ---*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains instruction defs that are common to all hw codegen
11// targets.
12//
13//===----------------------------------------------------------------------===//
14
15class AMDGPUInst <dag outs, dag ins, string asm, list<dag> pattern> : Instruction {
Tom Stellardf3b2a1e2013-02-06 17:32:29 +000016 field bit isRegisterLoad = 0;
17 field bit isRegisterStore = 0;
Tom Stellard75aadc22012-12-11 21:25:42 +000018
19 let Namespace = "AMDGPU";
20 let OutOperandList = outs;
21 let InOperandList = ins;
22 let AsmString = asm;
23 let Pattern = pattern;
24 let Itinerary = NullALU;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +000025
26 let TSFlags{63} = isRegisterLoad;
27 let TSFlags{62} = isRegisterStore;
Tom Stellard75aadc22012-12-11 21:25:42 +000028}
29
30class AMDGPUShaderInst <dag outs, dag ins, string asm, list<dag> pattern>
31 : AMDGPUInst<outs, ins, asm, pattern> {
32
33 field bits<32> Inst = 0xffffffff;
34
35}
36
37def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>;
Tom Stellard81d871d2013-11-13 23:36:50 +000038def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>;
Tom Stellard75aadc22012-12-11 21:25:42 +000039
Matt Arsenault4d7d3832014-04-15 22:32:49 +000040def u32imm : Operand<i32> {
41 let PrintMethod = "printU32ImmOperand";
42}
43
44def u16imm : Operand<i16> {
45 let PrintMethod = "printU16ImmOperand";
46}
47
48def u8imm : Operand<i8> {
49 let PrintMethod = "printU8ImmOperand";
50}
51
Tom Stellardbc5b5372014-06-13 16:38:59 +000052//===--------------------------------------------------------------------===//
53// Custom Operands
54//===--------------------------------------------------------------------===//
55def brtarget : Operand<OtherVT>;
56
Tom Stellardc0845332013-11-22 23:07:58 +000057//===----------------------------------------------------------------------===//
58// PatLeafs for floating-point comparisons
59//===----------------------------------------------------------------------===//
Tom Stellard75aadc22012-12-11 21:25:42 +000060
Tom Stellard0351ea22013-09-28 02:50:50 +000061def COND_OEQ : PatLeaf <
62 (cond),
63 [{return N->get() == ISD::SETOEQ || N->get() == ISD::SETEQ;}]
64>;
65
Tom Stellard0351ea22013-09-28 02:50:50 +000066def COND_OGT : PatLeaf <
67 (cond),
68 [{return N->get() == ISD::SETOGT || N->get() == ISD::SETGT;}]
69>;
70
Tom Stellard0351ea22013-09-28 02:50:50 +000071def COND_OGE : PatLeaf <
72 (cond),
73 [{return N->get() == ISD::SETOGE || N->get() == ISD::SETGE;}]
74>;
75
Tom Stellardc0845332013-11-22 23:07:58 +000076def COND_OLT : PatLeaf <
Tom Stellard75aadc22012-12-11 21:25:42 +000077 (cond),
Tom Stellardc0845332013-11-22 23:07:58 +000078 [{return N->get() == ISD::SETOLT || N->get() == ISD::SETLT;}]
Tom Stellard75aadc22012-12-11 21:25:42 +000079>;
80
Tom Stellardc0845332013-11-22 23:07:58 +000081def COND_OLE : PatLeaf <
Tom Stellard75aadc22012-12-11 21:25:42 +000082 (cond),
Tom Stellardc0845332013-11-22 23:07:58 +000083 [{return N->get() == ISD::SETOLE || N->get() == ISD::SETLE;}]
84>;
85
86def COND_UNE : PatLeaf <
87 (cond),
88 [{return N->get() == ISD::SETUNE || N->get() == ISD::SETNE;}]
89>;
90
91def COND_O : PatLeaf <(cond), [{return N->get() == ISD::SETO;}]>;
92def COND_UO : PatLeaf <(cond), [{return N->get() == ISD::SETUO;}]>;
93
94//===----------------------------------------------------------------------===//
95// PatLeafs for unsigned comparisons
96//===----------------------------------------------------------------------===//
97
98def COND_UGT : PatLeaf <(cond), [{return N->get() == ISD::SETUGT;}]>;
99def COND_UGE : PatLeaf <(cond), [{return N->get() == ISD::SETUGE;}]>;
100def COND_ULT : PatLeaf <(cond), [{return N->get() == ISD::SETULT;}]>;
101def COND_ULE : PatLeaf <(cond), [{return N->get() == ISD::SETULE;}]>;
102
103//===----------------------------------------------------------------------===//
104// PatLeafs for signed comparisons
105//===----------------------------------------------------------------------===//
106
107def COND_SGT : PatLeaf <(cond), [{return N->get() == ISD::SETGT;}]>;
108def COND_SGE : PatLeaf <(cond), [{return N->get() == ISD::SETGE;}]>;
109def COND_SLT : PatLeaf <(cond), [{return N->get() == ISD::SETLT;}]>;
110def COND_SLE : PatLeaf <(cond), [{return N->get() == ISD::SETLE;}]>;
111
112//===----------------------------------------------------------------------===//
113// PatLeafs for integer equality
114//===----------------------------------------------------------------------===//
115
116def COND_EQ : PatLeaf <
117 (cond),
118 [{return N->get() == ISD::SETEQ || N->get() == ISD::SETUEQ;}]
119>;
120
121def COND_NE : PatLeaf <
122 (cond),
123 [{return N->get() == ISD::SETNE || N->get() == ISD::SETUNE;}]
Tom Stellard75aadc22012-12-11 21:25:42 +0000124>;
125
Christian Konigb19849a2013-02-21 15:17:04 +0000126def COND_NULL : PatLeaf <
127 (cond),
128 [{return false;}]
129>;
130
Tom Stellard75aadc22012-12-11 21:25:42 +0000131//===----------------------------------------------------------------------===//
132// Load/Store Pattern Fragments
133//===----------------------------------------------------------------------===//
134
Tom Stellardbc5b5372014-06-13 16:38:59 +0000135def global_store : PatFrag<(ops node:$val, node:$ptr),
136 (store node:$val, node:$ptr), [{
137 return isGlobalStore(dyn_cast<StoreSDNode>(N));
138}]>;
139
140// Global address space loads
141def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
142 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
143}]>;
144
145// Constant address space loads
146def constant_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
147 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
148}]>;
149
Tom Stellard31209cc2013-07-15 19:00:09 +0000150def az_extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
151 LoadSDNode *L = cast<LoadSDNode>(N);
152 return L->getExtensionType() == ISD::ZEXTLOAD ||
153 L->getExtensionType() == ISD::EXTLOAD;
154}]>;
155
Tom Stellard33dd04b2013-07-23 01:47:52 +0000156def az_extloadi8 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
157 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
158}]>;
159
Tom Stellardc6f4a292013-08-26 15:05:59 +0000160def az_extloadi8_global : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{
161 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
162}]>;
163
Tom Stellard9f950332013-07-23 01:48:35 +0000164def sextloadi8_global : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{
Tom Stellard75aadc22012-12-11 21:25:42 +0000165 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
166}]>;
167
Tom Stellard33dd04b2013-07-23 01:47:52 +0000168def az_extloadi8_constant : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{
Tom Stellard9f950332013-07-23 01:48:35 +0000169 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
170}]>;
171
172def sextloadi8_constant : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{
173 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
174}]>;
175
Tom Stellardc6f4a292013-08-26 15:05:59 +0000176def az_extloadi8_local : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr), [{
177 return isLocalLoad(dyn_cast<LoadSDNode>(N));
178}]>;
179
180def sextloadi8_local : PatFrag<(ops node:$ptr), (sextloadi8 node:$ptr), [{
181 return isLocalLoad(dyn_cast<LoadSDNode>(N));
Tom Stellard33dd04b2013-07-23 01:47:52 +0000182}]>;
183
184def az_extloadi16 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
185 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
186}]>;
187
188def az_extloadi16_global : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{
189 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
190}]>;
191
Tom Stellard9f950332013-07-23 01:48:35 +0000192def sextloadi16_global : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{
Tom Stellard07a10a32013-06-03 17:39:43 +0000193 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
194}]>;
195
Tom Stellard9f950332013-07-23 01:48:35 +0000196def az_extloadi16_constant : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{
197 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
198}]>;
199
200def sextloadi16_constant : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{
201 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
202}]>;
203
Tom Stellardc6f4a292013-08-26 15:05:59 +0000204def az_extloadi16_local : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr), [{
205 return isLocalLoad(dyn_cast<LoadSDNode>(N));
206}]>;
207
208def sextloadi16_local : PatFrag<(ops node:$ptr), (sextloadi16 node:$ptr), [{
209 return isLocalLoad(dyn_cast<LoadSDNode>(N));
210}]>;
211
Tom Stellard31209cc2013-07-15 19:00:09 +0000212def az_extloadi32 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
213 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
214}]>;
215
216def az_extloadi32_global : PatFrag<(ops node:$ptr),
217 (az_extloadi32 node:$ptr), [{
218 return isGlobalLoad(dyn_cast<LoadSDNode>(N));
219}]>;
220
221def az_extloadi32_constant : PatFrag<(ops node:$ptr),
222 (az_extloadi32 node:$ptr), [{
223 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1);
224}]>;
225
Tom Stellardd3ee8c12013-08-16 01:12:06 +0000226def truncstorei8_global : PatFrag<(ops node:$val, node:$ptr),
227 (truncstorei8 node:$val, node:$ptr), [{
228 return isGlobalStore(dyn_cast<StoreSDNode>(N));
229}]>;
230
231def truncstorei16_global : PatFrag<(ops node:$val, node:$ptr),
232 (truncstorei16 node:$val, node:$ptr), [{
233 return isGlobalStore(dyn_cast<StoreSDNode>(N));
234}]>;
235
Tom Stellardc026e8b2013-06-28 15:47:08 +0000236def local_store : PatFrag<(ops node:$val, node:$ptr),
237 (store node:$val, node:$ptr), [{
Tom Stellardf3d166a2013-08-26 15:05:49 +0000238 return isLocalStore(dyn_cast<StoreSDNode>(N));
239}]>;
240
241def truncstorei8_local : PatFrag<(ops node:$val, node:$ptr),
242 (truncstorei8 node:$val, node:$ptr), [{
243 return isLocalStore(dyn_cast<StoreSDNode>(N));
244}]>;
245
246def truncstorei16_local : PatFrag<(ops node:$val, node:$ptr),
247 (truncstorei16 node:$val, node:$ptr), [{
248 return isLocalStore(dyn_cast<StoreSDNode>(N));
249}]>;
250
251def local_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{
252 return isLocalLoad(dyn_cast<LoadSDNode>(N));
Tom Stellardc026e8b2013-06-28 15:47:08 +0000253}]>;
254
Matt Arsenault72574102014-06-11 18:08:34 +0000255
256class local_binary_atomic_op<SDNode atomic_op> :
257 PatFrag<(ops node:$ptr, node:$value),
258 (atomic_op node:$ptr, node:$value), [{
259 return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
Tom Stellard13c68ef2013-09-05 18:38:09 +0000260}]>;
261
Matt Arsenault72574102014-06-11 18:08:34 +0000262
263def atomic_swap_local : local_binary_atomic_op<atomic_swap>;
264def atomic_load_add_local : local_binary_atomic_op<atomic_load_add>;
265def atomic_load_sub_local : local_binary_atomic_op<atomic_load_sub>;
266def atomic_load_and_local : local_binary_atomic_op<atomic_load_and>;
267def atomic_load_or_local : local_binary_atomic_op<atomic_load_or>;
268def atomic_load_xor_local : local_binary_atomic_op<atomic_load_xor>;
269def atomic_load_nand_local : local_binary_atomic_op<atomic_load_nand>;
270def atomic_load_min_local : local_binary_atomic_op<atomic_load_min>;
271def atomic_load_max_local : local_binary_atomic_op<atomic_load_max>;
272def atomic_load_umin_local : local_binary_atomic_op<atomic_load_umin>;
273def atomic_load_umax_local : local_binary_atomic_op<atomic_load_umax>;
Aaron Watry372cecf2013-09-06 20:17:42 +0000274
Tom Stellardd3ee8c12013-08-16 01:12:06 +0000275def mskor_global : PatFrag<(ops node:$val, node:$ptr),
276 (AMDGPUstore_mskor node:$val, node:$ptr), [{
277 return dyn_cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
278}]>;
279
Matt Arsenaultc793e1d2014-06-11 18:08:48 +0000280def atomic_cmp_swap_32_local :
281 PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
282 (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
283 AtomicSDNode *AN = cast<AtomicSDNode>(N);
284 return AN->getMemoryVT() == MVT::i32 &&
285 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
286}]>;
287
Matt Arsenaultcaa0ec22014-06-11 18:08:54 +0000288def atomic_cmp_swap_64_local :
289 PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
290 (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
291 AtomicSDNode *AN = cast<AtomicSDNode>(N);
292 return AN->getMemoryVT() == MVT::i64 &&
293 AN->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
294}]>;
295
Matt Arsenaultc793e1d2014-06-11 18:08:48 +0000296
Tom Stellard75aadc22012-12-11 21:25:42 +0000297class Constants {
298int TWO_PI = 0x40c90fdb;
299int PI = 0x40490fdb;
300int TWO_PI_INV = 0x3e22f983;
NAKAMURA Takumi4bb85f92013-10-28 04:07:23 +0000301int FP_UINT_MAX_PLUS_1 = 0x4f800000; // 1 << 32 in floating point encoding
Matt Arsenaultaeca2fa2014-05-31 06:47:42 +0000302int FP32_NEG_ONE = 0xbf800000;
303int FP32_ONE = 0x3f800000;
Tom Stellard75aadc22012-12-11 21:25:42 +0000304}
305def CONST : Constants;
306
307def FP_ZERO : PatLeaf <
308 (fpimm),
309 [{return N->getValueAPF().isZero();}]
310>;
311
312def FP_ONE : PatLeaf <
313 (fpimm),
314 [{return N->isExactlyValue(1.0);}]
315>;
316
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000317let isCodeGenOnly = 1, isPseudo = 1 in {
318
319let usesCustomInserter = 1 in {
Tom Stellard75aadc22012-12-11 21:25:42 +0000320
321class CLAMP <RegisterClass rc> : AMDGPUShaderInst <
322 (outs rc:$dst),
323 (ins rc:$src0),
324 "CLAMP $dst, $src0",
Matt Arsenault5d47d4a2014-06-12 21:15:44 +0000325 [(set f32:$dst, (AMDGPUclamp f32:$src0, (f32 FP_ZERO), (f32 FP_ONE)))]
Tom Stellard75aadc22012-12-11 21:25:42 +0000326>;
327
328class FABS <RegisterClass rc> : AMDGPUShaderInst <
329 (outs rc:$dst),
330 (ins rc:$src0),
331 "FABS $dst, $src0",
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000332 [(set f32:$dst, (fabs f32:$src0))]
Tom Stellard75aadc22012-12-11 21:25:42 +0000333>;
334
335class FNEG <RegisterClass rc> : AMDGPUShaderInst <
336 (outs rc:$dst),
337 (ins rc:$src0),
338 "FNEG $dst, $src0",
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000339 [(set f32:$dst, (fneg f32:$src0))]
Tom Stellard75aadc22012-12-11 21:25:42 +0000340>;
341
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000342} // usesCustomInserter = 1
343
344multiclass RegisterLoadStore <RegisterClass dstClass, Operand addrClass,
345 ComplexPattern addrPat> {
Tom Stellard81d871d2013-11-13 23:36:50 +0000346let UseNamedOperandTable = 1 in {
347
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000348 def RegisterLoad : AMDGPUShaderInst <
349 (outs dstClass:$dst),
350 (ins addrClass:$addr, i32imm:$chan),
351 "RegisterLoad $dst, $addr",
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000352 [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))]
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000353 > {
354 let isRegisterLoad = 1;
355 }
356
357 def RegisterStore : AMDGPUShaderInst <
358 (outs),
359 (ins dstClass:$val, addrClass:$addr, i32imm:$chan),
360 "RegisterStore $val, $addr",
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000361 [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))]
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000362 > {
363 let isRegisterStore = 1;
364 }
365}
Tom Stellard81d871d2013-11-13 23:36:50 +0000366}
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000367
368} // End isCodeGenOnly = 1, isPseudo = 1
Tom Stellard75aadc22012-12-11 21:25:42 +0000369
370/* Generic helper patterns for intrinsics */
371/* -------------------------------------- */
372
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000373class POW_Common <AMDGPUInst log_ieee, AMDGPUInst exp_ieee, AMDGPUInst mul>
374 : Pat <
375 (fpow f32:$src0, f32:$src1),
376 (exp_ieee (mul f32:$src1, (log_ieee f32:$src0)))
Tom Stellard75aadc22012-12-11 21:25:42 +0000377>;
378
379/* Other helper patterns */
380/* --------------------- */
381
382/* Extract element pattern */
Matt Arsenault530dde42014-02-26 23:00:58 +0000383class Extract_Element <ValueType sub_type, ValueType vec_type, int sub_idx,
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000384 SubRegIndex sub_reg>
385 : Pat<
386 (sub_type (vector_extract vec_type:$src, sub_idx)),
387 (EXTRACT_SUBREG $src, sub_reg)
Tom Stellard75aadc22012-12-11 21:25:42 +0000388>;
389
390/* Insert element pattern */
391class Insert_Element <ValueType elem_type, ValueType vec_type,
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000392 int sub_idx, SubRegIndex sub_reg>
393 : Pat <
394 (vector_insert vec_type:$vec, elem_type:$elem, sub_idx),
395 (INSERT_SUBREG $vec, $elem, sub_reg)
Tom Stellard75aadc22012-12-11 21:25:42 +0000396>;
397
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000398// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer
399// can handle COPY instructions.
Tom Stellard75aadc22012-12-11 21:25:42 +0000400// bitconvert pattern
401class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat <
402 (dt (bitconvert (st rc:$src0))),
403 (dt rc:$src0)
404>;
405
Tom Stellard40b7f1f2013-05-02 15:30:12 +0000406// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer
407// can handle COPY instructions.
Tom Stellard75aadc22012-12-11 21:25:42 +0000408class DwordAddrPat<ValueType vt, RegisterClass rc> : Pat <
409 (vt (AMDGPUdwordaddr (vt rc:$addr))),
410 (vt rc:$addr)
411>;
412
Tom Stellard9d10c4c2013-04-19 02:11:06 +0000413// BFI_INT patterns
414
Matt Arsenault6e439652014-06-10 19:00:20 +0000415multiclass BFIPatterns <Instruction BFI_INT, Instruction LoadImm32> {
Tom Stellard9d10c4c2013-04-19 02:11:06 +0000416
417 // Definition from ISA doc:
418 // (y & x) | (z & ~x)
419 def : Pat <
420 (or (and i32:$y, i32:$x), (and i32:$z, (not i32:$x))),
421 (BFI_INT $x, $y, $z)
422 >;
423
424 // SHA-256 Ch function
425 // z ^ (x & (y ^ z))
426 def : Pat <
427 (xor i32:$z, (and i32:$x, (xor i32:$y, i32:$z))),
428 (BFI_INT $x, $y, $z)
429 >;
430
Matt Arsenault6e439652014-06-10 19:00:20 +0000431 def : Pat <
432 (fcopysign f32:$src0, f32:$src1),
433 (BFI_INT (LoadImm32 0x7fffffff), $src0, $src1)
434 >;
435
436 def : Pat <
437 (f64 (fcopysign f64:$src0, f64:$src1)),
438 (INSERT_SUBREG (INSERT_SUBREG (f64 (IMPLICIT_DEF)),
439 (i32 (EXTRACT_SUBREG $src0, sub0)), sub0),
440 (BFI_INT (LoadImm32 0x7fffffff),
441 (i32 (EXTRACT_SUBREG $src0, sub1)),
442 (i32 (EXTRACT_SUBREG $src1, sub1))), sub1)
443 >;
Tom Stellard9d10c4c2013-04-19 02:11:06 +0000444}
445
Tom Stellardeac65dd2013-05-03 17:21:20 +0000446// SHA-256 Ma patterns
447
448// ((x & z) | (y & (x | z))) -> BFI_INT (XOR x, y), z, y
449class SHA256MaPattern <Instruction BFI_INT, Instruction XOR> : Pat <
450 (or (and i32:$x, i32:$z), (and i32:$y, (or i32:$x, i32:$z))),
451 (BFI_INT (XOR i32:$x, i32:$y), i32:$z, i32:$y)
452>;
453
Tom Stellard2b971eb2013-05-10 02:09:45 +0000454// Bitfield extract patterns
455
Tom Stellarda2a4b8e2014-01-23 18:49:33 +0000456/*
457
458XXX: The BFE pattern is not working correctly because the XForm is not being
459applied.
460
Tom Stellard2b971eb2013-05-10 02:09:45 +0000461def legalshift32 : ImmLeaf <i32, [{return Imm >=0 && Imm < 32;}]>;
462def bfemask : PatLeaf <(imm), [{return isMask_32(N->getZExtValue());}],
463 SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(CountTrailingOnes_32(N->getZExtValue()), MVT::i32);}]>>;
464
465class BFEPattern <Instruction BFE> : Pat <
466 (and (srl i32:$x, legalshift32:$y), bfemask:$z),
467 (BFE $x, $y, $z)
468>;
469
Tom Stellarda2a4b8e2014-01-23 18:49:33 +0000470*/
471
Tom Stellard5643c4a2013-05-20 15:02:19 +0000472// rotr pattern
473class ROTRPattern <Instruction BIT_ALIGN> : Pat <
474 (rotr i32:$src0, i32:$src1),
475 (BIT_ALIGN $src0, $src0, $src1)
476>;
477
Tom Stellard41fc7852013-07-23 01:48:42 +0000478// 24-bit arithmetic patterns
479def umul24 : PatFrag <(ops node:$x, node:$y), (mul node:$x, node:$y)>;
480
481/*
482class UMUL24Pattern <Instruction UMUL24> : Pat <
483 (mul U24:$x, U24:$y),
484 (UMUL24 $x, $y)
485>;
486*/
487
Matt Arsenaulteb260202014-05-22 18:00:15 +0000488class IMad24Pat<Instruction Inst> : Pat <
489 (add (AMDGPUmul_i24 i32:$src0, i32:$src1), i32:$src2),
490 (Inst $src0, $src1, $src2)
491>;
492
493class UMad24Pat<Instruction Inst> : Pat <
494 (add (AMDGPUmul_u24 i32:$src0, i32:$src1), i32:$src2),
495 (Inst $src0, $src1, $src2)
496>;
497
Matt Arsenault493c5f12014-05-22 18:00:24 +0000498multiclass Expand24IBitOps<Instruction MulInst, Instruction AddInst> {
499 def _expand_imad24 : Pat <
500 (AMDGPUmad_i24 i32:$src0, i32:$src1, i32:$src2),
501 (AddInst (MulInst $src0, $src1), $src2)
502 >;
Matt Arsenaultf15a0562014-05-22 18:00:20 +0000503
Matt Arsenault493c5f12014-05-22 18:00:24 +0000504 def _expand_imul24 : Pat <
505 (AMDGPUmul_i24 i32:$src0, i32:$src1),
506 (MulInst $src0, $src1)
507 >;
508}
Matt Arsenaultf15a0562014-05-22 18:00:20 +0000509
Matt Arsenault493c5f12014-05-22 18:00:24 +0000510multiclass Expand24UBitOps<Instruction MulInst, Instruction AddInst> {
511 def _expand_umad24 : Pat <
512 (AMDGPUmad_u24 i32:$src0, i32:$src1, i32:$src2),
513 (AddInst (MulInst $src0, $src1), $src2)
514 >;
515
516 def _expand_umul24 : Pat <
517 (AMDGPUmul_u24 i32:$src0, i32:$src1),
518 (MulInst $src0, $src1)
519 >;
520}
Matt Arsenaulteb260202014-05-22 18:00:15 +0000521
Matt Arsenaulta0050b02014-06-19 01:19:19 +0000522class RcpPat<Instruction RcpInst, ValueType vt> : Pat <
523 (fdiv FP_ONE, vt:$src),
524 (RcpInst $src)
525>;
526
527class RsqPat<Instruction RsqInst, ValueType vt> : Pat <
528 (AMDGPUrcp (fsqrt vt:$src)),
529 (RsqInst $src)
530>;
531
Tom Stellard75aadc22012-12-11 21:25:42 +0000532include "R600Instructions.td"
Tom Stellard2c1c9de2014-03-24 16:07:25 +0000533include "R700Instructions.td"
534include "EvergreenInstructions.td"
535include "CaymanInstructions.td"
Tom Stellard75aadc22012-12-11 21:25:42 +0000536
537include "SIInstrInfo.td"
538