Hexagon backend support
[oota-llvm.git] / lib / Target / Hexagon / HexagonIntrinsicsV4.td
1 //===- HexagonIntrinsicsV4.td - V4 Instruction intrinsics --*- 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 // This is populated based on the following specs:
10 // Hexagon V4 Architecture Extensions
11 // Application-Level Specification
12 // 80-V9418-12 Rev. A
13 // June 15, 2010
14
15
16 //
17 // ALU 32 types.
18 //
19
20 class si_ALU32_sisi_not<string opc, Intrinsic IntID>
21   : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
22              !strconcat("$dst = ", !strconcat(opc , "($src1, ~$src2)")),
23              [(set IntRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2))]>;
24
25 class di_ALU32_s8si<string opc, Intrinsic IntID>
26   : ALU32_rr<(outs DoubleRegs:$dst), (ins s8Imm:$src1, IntRegs:$src2),
27              !strconcat("$dst = ", !strconcat(opc , "(#$src1, $src2)")),
28              [(set DoubleRegs:$dst, (IntID imm:$src1, IntRegs:$src2))]>;
29
30 class di_ALU32_sis8<string opc, Intrinsic IntID>
31   : ALU32_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1, s8Imm:$src2),
32              !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2)")),
33              [(set DoubleRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
34
35 class qi_neg_ALU32_sisi<string opc, Intrinsic IntID>
36   : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
37              !strconcat("$dst = !", !strconcat(opc , "($src1, $src2)")),
38              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2))]>;
39
40 class qi_neg_ALU32_sis10<string opc, Intrinsic IntID>
41   : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$src1, s10Imm:$src2),
42              !strconcat("$dst = !", !strconcat(opc , "($src1, #$src2)")),
43              [(set PredRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
44
45 class qi_neg_ALU32_siu9<string opc, Intrinsic IntID>
46   : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$src1, u9Imm:$src2),
47              !strconcat("$dst = !", !strconcat(opc , "($src1, #$src2)")),
48              [(set PredRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
49
50 class si_neg_ALU32_sisi<string opc, Intrinsic IntID>
51   : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
52              !strconcat("$dst = !", !strconcat(opc , "($src1, $src2)")),
53              [(set IntRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2))]>;
54
55 class si_neg_ALU32_sis8<string opc, Intrinsic IntID>
56   : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, s8Imm:$src2),
57              !strconcat("$dst = !", !strconcat(opc , "($src1, #$src2)")),
58              [(set IntRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
59
60 class si_ALU32_sis8<string opc, Intrinsic IntID>
61   : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, s8Imm:$src2),
62              !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2)")),
63              [(set IntRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
64
65
66 //
67 // SInst Classes.
68 //
69 class qi_neg_SInst_qiqi<string opc, Intrinsic IntID>
70   : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
71              !strconcat("$dst = !", !strconcat(opc , "($src1, $src2)")),
72              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2))]>;
73
74 class qi_SInst_qi_andqiqi_neg<string opc, Intrinsic IntID>
75   : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
76                                      IntRegs:$src3),
77              !strconcat("$dst = ", !strconcat(opc ,
78                                               "($src1, and($src2, !$src3)")),
79              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
80                                          IntRegs:$src3))]>;
81
82 class qi_SInst_qi_andqiqi<string opc, Intrinsic IntID>
83   : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
84                                      IntRegs:$src3),
85              !strconcat("$dst = ", !strconcat(opc ,
86                                               "($src1, and($src2, $src3)")),
87              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
88                                          IntRegs:$src3))]>;
89
90 class qi_SInst_qi_orqiqi_neg<string opc, Intrinsic IntID>
91   : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
92                                      IntRegs:$src3),
93              !strconcat("$dst = ", !strconcat(opc ,
94                                               "($src1, or($src2, !$src3)")),
95              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
96                                          IntRegs:$src3))]>;
97
98 class qi_SInst_qi_orqiqi<string opc, Intrinsic IntID>
99   : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
100                                      IntRegs:$src3),
101              !strconcat("$dst = ", !strconcat(opc ,
102                                               "($src1, or($src2, $src3)")),
103              [(set PredRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
104                                          IntRegs:$src3))]>;
105
106 class si_SInst_si_addsis6<string opc, Intrinsic IntID>
107   : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, s6Imm:$src3),
108              !strconcat("$dst = ", !strconcat(opc ,
109                                               "($src1, add($src2, #$src3)")),
110              [(set IntRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
111                                         imm:$src3))]>;
112
113 class si_SInst_si_subs6si<string opc, Intrinsic IntID>
114   : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s6Imm:$src2, IntRegs:$src3),
115              !strconcat("$dst = ", !strconcat(opc ,
116                                               "($src1, sub(#$src2, $src3)")),
117              [(set IntRegs:$dst, (IntID IntRegs:$src1, imm:$src2,
118                                         IntRegs:$src3))]>;
119
120 class di_ALU64_didi_neg<string opc, Intrinsic IntID>
121   : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, DoubleRegs:$src2),
122           !strconcat("$dst = ", !strconcat(opc , "($src1, ~$src2)")),
123           [(set DoubleRegs:$dst, (IntID DoubleRegs:$src1, DoubleRegs:$src2))]>;
124
125 class di_MInst_dididi_xacc<string opc, Intrinsic IntID>
126   : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$dst2, DoubleRegs:$src1,
127                                            DoubleRegs:$src2),
128                !strconcat("$dst ^= ", !strconcat(opc , "($src1, $src2)")),
129                [(set DoubleRegs:$dst, (IntID DoubleRegs:$dst2, DoubleRegs:$src1,
130                                              DoubleRegs:$src2))],
131                "$dst2 = $dst">;
132
133 class si_MInst_sisisi_and<string opc, Intrinsic IntID>
134   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
135                                     IntRegs:$src3),
136              !strconcat("$dst &= ", !strconcat(opc , "($src2, $src3)")),
137              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
138                                         IntRegs:$src3))]>;
139
140 class si_MInst_sisisi_andn<string opc, Intrinsic IntID>
141   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
142                                     IntRegs:$src3),
143              !strconcat("$dst &= ", !strconcat(opc , "($src2, ~$src3)")),
144              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
145                                         IntRegs:$src3))]>;
146
147 class si_SInst_sisis10_andi<string opc, Intrinsic IntID>
148   : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, s10Imm:$src3),
149              !strconcat("$dst = ", !strconcat(opc ,
150                                               "($src1, and($src2, #$src3))")),
151              [(set IntRegs:$dst, (IntID IntRegs:$src1, IntRegs:$src2,
152                                         imm:$src3))]>;
153
154 class si_MInst_sisisi_xor<string opc, Intrinsic IntID>
155   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
156                                     IntRegs:$src3),
157              !strconcat("$dst ^= ", !strconcat(opc , "($src2, $src3)")),
158              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
159                                         IntRegs:$src3))]>;
160
161 class si_MInst_sisisi_xorn<string opc, Intrinsic IntID>
162   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
163                                     IntRegs:$src3),
164              !strconcat("$dst ^= ", !strconcat(opc , "($src2, ~$src3)")),
165              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
166                                         IntRegs:$src3))]>;
167
168 class si_SInst_sisis10_or<string opc, Intrinsic IntID>
169   : SInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2, s10Imm:$src3),
170              !strconcat("$dst |= ", !strconcat(opc , "($src2, #$src3)")),
171              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
172                                         imm:$src3))]>;
173
174 class si_MInst_sisisi_or<string opc, Intrinsic IntID>
175   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
176                                     IntRegs:$src3),
177              !strconcat("$dst |= ", !strconcat(opc , "($src2, $src3)")),
178              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
179                                         IntRegs:$src3))]>;
180
181 class si_MInst_sisisi_orn<string opc, Intrinsic IntID>
182   : MInst<(outs IntRegs:$dst), (ins IntRegs:$dst1, IntRegs:$src2,
183                                     IntRegs:$src3),
184              !strconcat("$dst |= ", !strconcat(opc , "($src2, ~$src3)")),
185              [(set IntRegs:$dst, (IntID IntRegs:$dst1, IntRegs:$src2,
186                                         IntRegs:$src3))]>;
187
188 class si_SInst_siu5_sat<string opc, Intrinsic IntID>
189   : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
190           !strconcat("$dst = ", !strconcat(opc , "($src1, #$src2):sat")),
191           [(set IntRegs:$dst, (IntID IntRegs:$src1, imm:$src2))]>;
192
193
194 /********************************************************************
195 *            ALU32/ALU                                              *
196 *********************************************************************/
197
198 // ALU32 / ALU / Logical Operations.
199 def Hexagon_A4_orn  : si_ALU32_sisi_not <"or",  int_hexagon_A4_orn>;
200 def Hexagon_A4_andn : si_ALU32_sisi_not <"and", int_hexagon_A4_andn>;
201
202
203 /********************************************************************
204 *            ALU32/PERM                                             *
205 *********************************************************************/
206
207 // ALU32 / PERM / Combine Words Into Doublewords.
208 def Hexagon_A4_combineir : di_ALU32_s8si  <"combine", int_hexagon_A4_combineir>;
209 def Hexagon_A4_combineri : di_ALU32_sis8  <"combine", int_hexagon_A4_combineri>;
210
211
212 /********************************************************************
213 *            ALU32/PRED                                             *
214 *********************************************************************/
215
216 // ALU32 / PRED / Conditional Shift Halfword.
217 // ALU32 / PRED / Conditional Sign Extend.
218 // ALU32 / PRED / Conditional Zero Extend.
219 // ALU32 / PRED / Compare.
220 def Hexagon_C4_cmpneq  : qi_neg_ALU32_sisi  <"cmp.eq", int_hexagon_C4_cmpneq>;
221 def Hexagon_C4_cmpneqi : qi_neg_ALU32_sis10 <"cmp.eq", int_hexagon_C4_cmpneqi>;
222 def Hexagon_C4_cmplte  : qi_neg_ALU32_sisi  <"cmp.gt", int_hexagon_C4_cmplte>;
223 def Hexagon_C4_cmpltei : qi_neg_ALU32_sis10 <"cmp.gt", int_hexagon_C4_cmpltei>;
224 def Hexagon_C4_cmplteu : qi_neg_ALU32_sisi  <"cmp.gtu",int_hexagon_C4_cmplteu>;
225 def Hexagon_C4_cmplteui: qi_neg_ALU32_siu9  <"cmp.gtu",int_hexagon_C4_cmplteui>;
226
227 // ALU32 / PRED / cmpare To General Register.
228 def Hexagon_A4_rcmpneq : si_neg_ALU32_sisi <"cmp.eq", int_hexagon_A4_rcmpneq>;
229 def Hexagon_A4_rcmpneqi: si_neg_ALU32_sis8 <"cmp.eq", int_hexagon_A4_rcmpneqi>;
230 def Hexagon_A4_rcmpeq  : si_ALU32_sisi     <"cmp.eq", int_hexagon_A4_rcmpeq>;
231 def Hexagon_A4_rcmpeqi : si_ALU32_sis8     <"cmp.eq", int_hexagon_A4_rcmpeqi>;
232
233
234 /********************************************************************
235 *            CR                                                     *
236 *********************************************************************/
237
238 // CR / Corner Detection Acceleration.
239 def Hexagon_C4_fastcorner9:
240   qi_SInst_qiqi<"fastcorner9", int_hexagon_C4_fastcorner9>;
241 def Hexagon_C4_fastcorner9_not:
242   qi_neg_SInst_qiqi<"fastcorner9",int_hexagon_C4_fastcorner9_not>;
243
244 // CR / Logical Operations On Predicates.
245 def Hexagon_C4_and_andn:
246   qi_SInst_qi_andqiqi_neg         <"and",      int_hexagon_C4_and_andn>;
247 def Hexagon_C4_and_and:
248   qi_SInst_qi_andqiqi             <"and",      int_hexagon_C4_and_and>;
249 def Hexagon_C4_and_orn:
250   qi_SInst_qi_orqiqi_neg          <"and",      int_hexagon_C4_and_orn>;
251 def Hexagon_C4_and_or:
252   qi_SInst_qi_orqiqi              <"and",      int_hexagon_C4_and_or>;
253 def Hexagon_C4_or_andn:
254   qi_SInst_qi_andqiqi_neg         <"or",       int_hexagon_C4_or_andn>;
255 def Hexagon_C4_or_and:
256   qi_SInst_qi_andqiqi             <"or",       int_hexagon_C4_or_and>;
257 def Hexagon_C4_or_orn:
258   qi_SInst_qi_orqiqi_neg          <"or",       int_hexagon_C4_or_orn>;
259 def Hexagon_C4_or_or:
260   qi_SInst_qi_orqiqi              <"or",       int_hexagon_C4_or_or>;
261
262
263 /********************************************************************
264 *            XTYPE/ALU                                              *
265 *********************************************************************/
266
267 // XTYPE / ALU / Add And Accumulate.
268 def Hexagon_S4_addaddi:
269   si_SInst_si_addsis6             <"add",      int_hexagon_S4_addaddi>;
270 def Hexagon_S4_subaddi:
271   si_SInst_si_subs6si             <"add",      int_hexagon_S4_subaddi>;
272
273 // XTYPE / ALU / Logical Doublewords.
274 def Hexagon_S4_andnp:
275   di_ALU64_didi_neg               <"and",      int_hexagon_A4_andnp>;
276 def Hexagon_S4_ornp:
277   di_ALU64_didi_neg               <"or",       int_hexagon_A4_ornp>;
278
279 // XTYPE / ALU / Logical-logical Doublewords.
280 def Hexagon_M4_xor_xacc:
281   di_MInst_dididi_xacc            <"xor",      int_hexagon_M4_xor_xacc>;
282
283 // XTYPE / ALU / Logical-logical Words.
284 def HEXAGON_M4_and_and:
285   si_MInst_sisisi_and             <"and",      int_hexagon_M4_and_and>;
286 def HEXAGON_M4_and_or:
287   si_MInst_sisisi_and             <"or",       int_hexagon_M4_and_or>;
288 def HEXAGON_M4_and_xor:
289   si_MInst_sisisi_and             <"xor",      int_hexagon_M4_and_xor>;
290 def HEXAGON_M4_and_andn:
291   si_MInst_sisisi_andn            <"and",      int_hexagon_M4_and_andn>;
292 def HEXAGON_M4_xor_and:
293   si_MInst_sisisi_xor             <"and",      int_hexagon_M4_xor_and>;
294 def HEXAGON_M4_xor_or:
295   si_MInst_sisisi_xor             <"or",       int_hexagon_M4_xor_or>;
296 def HEXAGON_M4_xor_andn:
297   si_MInst_sisisi_xorn            <"and",      int_hexagon_M4_xor_andn>;
298 def HEXAGON_M4_or_and:
299   si_MInst_sisisi_or              <"and",      int_hexagon_M4_or_and>;
300 def HEXAGON_M4_or_or:
301   si_MInst_sisisi_or              <"or",       int_hexagon_M4_or_or>;
302 def HEXAGON_M4_or_xor:
303   si_MInst_sisisi_or              <"xor",      int_hexagon_M4_or_xor>;
304 def HEXAGON_M4_or_andn:
305   si_MInst_sisisi_orn             <"and",      int_hexagon_M4_or_andn>;
306 def HEXAGON_S4_or_andix:
307   si_SInst_sisis10_andi           <"or",       int_hexagon_S4_or_andix>;
308 def HEXAGON_S4_or_andi:
309   si_SInst_sisis10_or             <"and",      int_hexagon_S4_or_andi>;
310 def HEXAGON_S4_or_ori:
311   si_SInst_sisis10_or             <"or",       int_hexagon_S4_or_ori>;
312
313 // XTYPE / ALU / Modulo wrap.
314 def HEXAGON_A4_modwrapu:
315   si_ALU64_sisi                   <"modwrap",  int_hexagon_A4_modwrapu>;
316
317 // XTYPE / ALU / Round.
318 def HEXAGON_A4_cround_ri:
319   si_SInst_siu5                   <"cround",   int_hexagon_A4_cround_ri>;
320 def HEXAGON_A4_cround_rr:
321   si_SInst_sisi                   <"cround",   int_hexagon_A4_cround_rr>;
322 def HEXAGON_A4_round_ri:
323   si_SInst_siu5                   <"round",    int_hexagon_A4_round_ri>;
324 def HEXAGON_A4_round_rr:
325   si_SInst_sisi                   <"round",    int_hexagon_A4_round_rr>;
326 def HEXAGON_A4_round_ri_sat:
327   si_SInst_siu5_sat               <"round",    int_hexagon_A4_round_ri_sat>;
328 def HEXAGON_A4_round_rr_sat:
329   si_SInst_sisi_sat               <"round",    int_hexagon_A4_round_rr_sat>;
330
331 // XTYPE / ALU / Vector reduce add unsigned halfwords.
332 // XTYPE / ALU / Vector add bytes.
333 // XTYPE / ALU / Vector conditional negate.
334 // XTYPE / ALU / Vector maximum bytes.
335 // XTYPE / ALU / Vector reduce maximum halfwords.
336 // XTYPE / ALU / Vector reduce maximum words.
337 // XTYPE / ALU / Vector minimum bytes.
338 // XTYPE / ALU / Vector reduce minimum halfwords.
339 // XTYPE / ALU / Vector reduce minimum words.
340 // XTYPE / ALU / Vector subtract bytes.
341
342
343 /********************************************************************
344 *            XTYPE/BIT                                              *
345 *********************************************************************/
346
347 // XTYPE / BIT / Count leading.
348 // XTYPE / BIT / Count trailing.
349 // XTYPE / BIT / Extract bitfield.
350 // XTYPE / BIT / Masked parity.
351 // XTYPE / BIT / Bit reverse.
352 // XTYPE / BIT / Split bitfield.
353
354
355 /********************************************************************
356 *            XTYPE/COMPLEX                                          *
357 *********************************************************************/
358
359 // XTYPE / COMPLEX / Complex add/sub halfwords.
360 // XTYPE / COMPLEX / Complex add/sub words.
361 // XTYPE / COMPLEX / Complex multiply 32x16.
362 // XTYPE / COMPLEX / Vector reduce complex rotate.
363
364
365 /********************************************************************
366 *            XTYPE/MPY                                              *
367 *********************************************************************/
368
369 // XTYPE / COMPLEX / Complex add/sub halfwords.