1;; Multiplication patterns for TI C6X.
2;; This file is processed by genmult.sh to produce two variants of each
3;; pattern, a normal one and a real_mult variant for modulo scheduling.
4;; Copyright (C) 2010-2013 Free Software Foundation, Inc.
5;; Contributed by Bernd Schmidt <bernds@codesourcery.com>
6;; Contributed by CodeSourcery.
7;;
8;; This file is part of GCC.
9;;
10;; GCC is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 3, or (at your option)
13;; any later version.
14;;
15;; GCC is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18;; GNU General Public License for more details.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GCC; see the file COPYING3.  If not see
22;; <http://www.gnu.org/licenses/>.
23
24;; -------------------------------------------------------------------------
25;; Miscellaneous insns that execute on the M units
26;; -------------------------------------------------------------------------
27
28(define_insn "rotlsi3_VARIANT_"
29  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
30        (rotate:SI (match_operand:SI 1 "register_operand" "a,b,?b,?a")
31		   (match_operand:SI 2 "reg_or_ucst5_operand" "aIu5,bIu5,aIu5,bIu5"))_CBRK_)]
32  "TARGET_INSNS_64"
33  "%|%.\\trotl\\t%$\\t%1, %2, %_MODk_0"
34  [(set_attr "units" "m")
35   (set_attr "type" "mpy2")
36   (set_attr "cross" "n,n,y,y")])
37
38(define_insn "bitrevsi2_VARIANT_"
39  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_A_,_B_,_B_")
40	(unspec:SI [(match_operand:SI 1 "register_operand" "a,?b,b,?a")]
41		   UNSPEC_BITREV)_CBRK_)]
42  "TARGET_INSNS_64"
43  "%|%.\\tbitr\\t%$\\t%1, %_MODk_0"
44  [(set_attr "units" "m")
45   (set_attr "type" "mpy2")
46   (set_attr "cross" "n,y,n,y")])
47
48;; Vector average.
49
50(define_insn "avgv2hi3_VARIANT_"
51  [(_SET_ _OBRK_(match_operand:_MV2HI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
52        (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "a,b,?b,?a")
53		      (match_operand:V2HI 2 "register_operand" "a,b,a,b")] UNSPEC_AVG)_CBRK_)]
54  "TARGET_INSNS_64"
55  "%|%.\\tavg2\\t%$\\t%1, %2, %_MODk_0"
56  [(set_attr "units" "m")
57   (set_attr "type" "mpy2")
58   (set_attr "cross" "n,n,y,y")])
59
60(define_insn "uavgv4qi3_VARIANT_"
61  [(_SET_ _OBRK_(match_operand:_MV4QI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
62        (unspec:V4QI [(match_operand:V4QI 1 "register_operand" "a,b,?b,?a")
63		      (match_operand:V4QI 2 "register_operand" "a,b,a,b")] UNSPEC_AVG)_CBRK_)]
64  "TARGET_INSNS_64"
65  "%|%.\\tavgu4\\t%$\\t%1, %2, %_MODk_0"
66  [(set_attr "units" "m")
67   (set_attr "type" "mpy2")
68   (set_attr "cross" "n,n,y,y")])
69
70;; -------------------------------------------------------------------------
71;; Multiplication
72;; -------------------------------------------------------------------------
73
74(define_insn "mulhi3_VARIANT_"
75  [(_SET_ _OBRK_(match_operand:HI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
76        (mult:HI (match_operand:HI 1 "register_operand" "a,b,?b,?a")
77                 (match_operand:HI 2 "reg_or_scst5_operand" "aIs5,bIs5,aIs5,bIs5"))_CBRK_)]
78  ""
79  "%|%.\\tmpy\\t%$\\t%2, %1, %_MODk_0"
80  [(set_attr "type" "mpy2")
81   (set_attr "units" "m")
82   (set_attr "op_pattern" "sxs")
83   (set_attr "cross" "n,n,y,y")])
84
85(define_insn "mulhisi3_const_VARIANT_"
86  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A__B_")
87        (mult:SI (sign_extend:SI
88		  (match_operand:HI 1 "register_operand" "a,b,?ab"))
89                 (match_operand:HI 2 "scst5_operand" "Is5,Is5,Is5"))_CBRK_)]
90  ""
91  "%|%.\\tmpy\\t%$\\t%2, %1, %_MODk_0"
92  [(set_attr "type" "mpy2")
93   (set_attr "units" "m")
94   (set_attr "cross" "n,n,y")])
95
96(define_insn "*mulhisi3_insn_VARIANT_"
97  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
98        (mult:SI (sign_extend:SI
99		  (match_operand:HI 1 "register_operand" "%a,b,?a,?b"))
100                 (sign_extend:SI
101		  (match_operand:HI 2 "reg_or_scst5_operand" "a,b,b,a")))_CBRK_)]
102  ""
103  "%|%.\\tmpy\\t%$\\t%1, %2, %_MODk_0"
104  [(set_attr "type" "mpy2")
105   (set_attr "units" "m")
106   (set_attr "op_pattern" "ssx")
107   (set_attr "cross" "n,n,y,y")])
108
109(define_insn "mulhisi3_lh_VARIANT_"
110  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
111        (mult:SI (sign_extend:SI
112		  (match_operand:HI 1 "register_operand" "a,b,?a,?b"))
113                 (ashiftrt:SI
114		  (match_operand:SI 2 "register_operand" "a,b,b,a")
115		  (const_int 16)))_CBRK_)]
116  ""
117  "%|%.\\tmpylh\\t%$\\t%1, %2, %_MODk_0"
118  [(set_attr "type" "mpy2")
119   (set_attr "units" "m")
120   (set_attr "cross" "n,n,y,y")])
121
122(define_insn "mulhisi3_hl_VARIANT_"
123  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
124        (mult:SI (ashiftrt:SI
125		  (match_operand:SI 1 "register_operand" "a,b,?a,?b")
126		  (const_int 16))
127                 (sign_extend:SI
128		  (match_operand:HI 2 "register_operand" "a,b,b,a")))_CBRK_)]
129  ""
130  "%|%.\\tmpyhl\\t%$\\t%1, %2, %_MODk_0"
131  [(set_attr "type" "mpy2")
132   (set_attr "units" "m")
133   (set_attr "cross" "n,n,y,y")])
134
135(define_insn "mulhisi3_hh_VARIANT_"
136  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
137        (mult:SI (ashiftrt:SI
138		  (match_operand:SI 1 "register_operand" "%a,b,?a,?b")
139		  (const_int 16))
140                 (ashiftrt:SI
141		  (match_operand:SI 2 "register_operand" "a,b,b,a")
142		  (const_int 16)))_CBRK_)]
143  ""
144  "%|%.\\tmpyh\\t%$\\t%1, %2, %_MODk_0"
145  [(set_attr "type" "mpy2")
146   (set_attr "units" "m")
147   (set_attr "cross" "n,n,y,y")])
148
149(define_insn "umulhisi3_VARIANT_"
150  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
151        (mult:SI (zero_extend:SI
152		  (match_operand:HI 1 "register_operand" "%a,b,?a,?b"))
153                 (zero_extend:SI
154		  (match_operand:HI 2 "register_operand" "a,b,b,a")))_CBRK_)]
155  ""
156  "%|%.\\tmpyu\\t%$\\t%1, %2, %_MODk_0"
157  [(set_attr "type" "mpy2")
158   (set_attr "units" "m")
159   (set_attr "cross" "n,n,y,y")])
160
161(define_insn "umulhisi3_lh_VARIANT_"
162  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
163        (mult:SI (zero_extend:SI
164		  (match_operand:HI 1 "register_operand" "a,b,?a,?b"))
165                 (lshiftrt:SI
166		  (match_operand:SI 2 "register_operand" "a,b,b,a")
167		  (const_int 16)))_CBRK_)]
168  ""
169  "%|%.\\tmpylhu\\t%$\\t%1, %2, %_MODk_0"
170  [(set_attr "type" "mpy2")
171   (set_attr "units" "m")
172   (set_attr "cross" "n,n,y,y")])
173
174(define_insn "umulhisi3_hl_VARIANT_"
175  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
176        (mult:SI (lshiftrt:SI
177		  (match_operand:SI 1 "register_operand" "a,b,?a,?b")
178		  (const_int 16))
179                 (zero_extend:SI
180		  (match_operand:HI 2 "register_operand" "a,b,b,a")))_CBRK_)]
181  ""
182  "%|%.\\tmpyhlu\\t%$\\t%1, %2, %_MODk_0"
183  [(set_attr "type" "mpy2")
184   (set_attr "units" "m")
185   (set_attr "cross" "n,n,y,y")])
186
187(define_insn "umulhisi3_hh_VARIANT_"
188  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
189        (mult:SI (lshiftrt:SI
190		  (match_operand:SI 1 "register_operand" "%a,b,?a,?b")
191		  (const_int 16))
192                 (lshiftrt:SI
193		  (match_operand:SI 2 "register_operand" "a,b,b,a")
194		  (const_int 16)))_CBRK_)]
195  ""
196  "%|%.\\tmpyhu\\t%$\\t%1, %2, %_MODk_0"
197  [(set_attr "type" "mpy2")
198   (set_attr "units" "m")
199   (set_attr "cross" "n,n,y,y")])
200
201(define_insn "usmulhisi3_const_VARIANT_"
202  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A__B_")
203        (mult:SI (zero_extend:SI
204		  (match_operand:HI 1 "register_operand" "a,b,?ab"))
205                 (match_operand:SI 2 "scst5_operand" "Is5,Is5,Is5"))_CBRK_)]
206  ""
207  "%|%.\\tmpysu\\t%$\\t%2, %1, %_MODk_0"
208  [(set_attr "type" "mpy2")
209   (set_attr "units" "m")
210   (set_attr "cross" "n,n,y")])
211
212(define_insn "*usmulhisi3_insn_VARIANT_"
213  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
214        (mult:SI (zero_extend:SI
215		  (match_operand:HI 1 "register_operand" "a,b,?a,?b"))
216                 (sign_extend:SI
217		  (match_operand:HI 2 "reg_or_scst5_operand" "aIs5,bIs5,bIs5,aIs5")))_CBRK_)]
218  ""
219  "%|%.\\tmpyus\\t%$\\t%1, %2, %_MODk_0"
220  [(set_attr "type" "mpy2")
221   (set_attr "units" "m")
222   (set_attr "cross" "n,n,y,y")])
223
224(define_insn "usmulhisi3_lh_VARIANT_"
225  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
226	(mult:SI (zero_extend:SI
227		  (match_operand:HI 1 "register_operand" "a,b,?a,?b"))
228                 (ashiftrt:SI
229		  (match_operand:SI 2 "register_operand" "a,b,b,a")
230		  (const_int 16)))_CBRK_)]
231  ""
232  "%|%.\\tmpyluhs\\t%$\\t%1, %2, %_MODk_0"
233  [(set_attr "type" "mpy2")
234   (set_attr "units" "m")
235   (set_attr "cross" "n,n,y,y")])
236
237(define_insn "usmulhisi3_hl_VARIANT_"
238  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
239        (mult:SI (lshiftrt:SI
240		  (match_operand:SI 1 "register_operand" "a,b,?a,?b")
241		  (const_int 16))
242                 (sign_extend:SI
243		  (match_operand:HI 2 "register_operand" "a,b,b,a")))_CBRK_)]
244  ""
245  "%|%.\\tmpyhuls\\t%$\\t%1, %2, %_MODk_0"
246  [(set_attr "type" "mpy2")
247   (set_attr "units" "m")
248   (set_attr "cross" "n,n,y,y")])
249
250(define_insn "usmulhisi3_hh_VARIANT_"
251  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
252        (mult:SI (lshiftrt:SI
253		  (match_operand:SI 1 "register_operand" "a,b,?a,?b")
254		  (const_int 16))
255                 (ashiftrt:SI
256		  (match_operand:SI 2 "register_operand" "a,b,b,a")
257		  (const_int 16)))_CBRK_)]
258  ""
259  "%|%.\\tmpyhus\\t%$\\t%1, %2, %_MODk_0"
260  [(set_attr "type" "mpy2")
261   (set_attr "units" "m")
262   (set_attr "cross" "n,n,y,y")])
263
264(define_insn "mulsi3_insn_VARIANT_"
265  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
266	(mult:SI (match_operand:SI 1 "register_operand" "%a,b,?a,?b")
267		 (match_operand:SI 2 "register_operand" "a,b,b,a"))_CBRK_)]
268  "TARGET_MPY32"
269  "%|%.\\tmpy32\\t%$\\t%1, %2, %_MODk_0"
270 [(set_attr "type" "mpy4")
271  (set_attr "units" "m")
272  (set_attr "cross" "n,n,y,y")])
273
274(define_insn "<u>mulsidi3_VARIANT_"
275  [(_SET_ _OBRK_(match_operand:DI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
276        (mult:DI (any_ext:DI
277		  (match_operand:SI 1 "register_operand" "%a,b,?a,?b"))
278                 (any_ext:DI
279		  (match_operand:SI 2 "register_operand" "a,b,b,a")))_CBRK_)]
280  "TARGET_MPY32"
281  "%|%.\\tmpy32<u>\\t%$\\t%1, %2, %_MODK_0"
282  [(set_attr "type" "mpy4")
283   (set_attr "units" "m")
284   (set_attr "cross" "n,n,y,y")])
285
286(define_insn "usmulsidi3_VARIANT_"
287  [(_SET_ _OBRK_(match_operand:DI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
288        (mult:DI (zero_extend:DI
289		  (match_operand:SI 1 "register_operand" "a,b,?a,?b"))
290                 (sign_extend:DI
291		  (match_operand:SI 2 "register_operand" "a,b,b,a")))_CBRK_)]
292  "TARGET_MPY32"
293  "%|%.\\tmpy32us\\t%$\\t%1, %2, %_MODK_0"
294  [(set_attr "type" "mpy4")
295   (set_attr "units" "m")
296   (set_attr "cross" "n,n,y,y")])
297
298;; Widening vector multiply and dot product
299
300(define_insn "mulv2hiv2si3_VARIANT_"
301  [(_SET_ _OBRK_(match_operand:V2SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
302	(mult:V2SI
303	 (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" "a,b,a,b"))
304	 (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" "a,b,?b,?a")))_CBRK_)]
305  "TARGET_INSNS_64"
306  "%|%.\\tmpy2\\t%$\\t%1, %2, %_MODk_0"
307 [(set_attr "type" "mpy4")
308  (set_attr "units" "m")
309  (set_attr "cross" "n,n,y,y")])
310
311(define_insn "umulv4qiv4hi3_VARIANT_"
312  [(_SET_ _OBRK_(match_operand:V4HI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
313	(mult:V4HI
314	 (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" "a,b,a,b"))
315	 (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" "a,b,?b,?a")))_CBRK_)]
316  "TARGET_INSNS_64"
317  "%|%.\\tmpyu4\\t%$\\t%1, %2, %_MODk_0"
318  [(set_attr "type" "mpy4")
319   (set_attr "units" "m")
320   (set_attr "cross" "n,n,y,y")])
321
322(define_insn "usmulv4qiv4hi3_VARIANT_"
323  [(_SET_ _OBRK_(match_operand:V4HI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
324	(mult:V4HI
325	 (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" "a,b,?b,?a"))
326	 (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" "a,b,a,b")))_CBRK_)]
327  "TARGET_INSNS_64"
328  "%|%.\\tmpyus4\\t%$\\t%1, %2, %_MODk_0"
329  [(set_attr "type" "mpy4")
330   (set_attr "units" "m")
331   (set_attr "cross" "n,n,y,y")])
332
333(define_insn "dotv2hi_VARIANT_"
334  [(_SET_ _OBRK_(match_operand:SI 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
335	(plus:SI
336	  (mult:SI
337	    (sign_extend:SI
338	      (vec_select:HI
339		(match_operand:V2HI 1 "register_operand" "a,b,a,b")
340		(parallel [(const_int 0)])))
341	    (sign_extend:SI
342	      (vec_select:HI
343		(match_operand:V2HI 2 "register_operand" "a,b,?b,?a")
344		(parallel [(const_int 0)]))))
345	  (mult:SI
346	    (sign_extend:SI
347	      (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
348	    (sign_extend:SI
349	      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))_CBRK_)]
350  "TARGET_INSNS_64"
351  "%|%.\\tdotp2\\t%$\\t%1, %2, %_MODk_0"
352  [(set_attr "type" "mpy4")
353   (set_attr "units" "m")
354   (set_attr "cross" "n,n,y,y")])
355
356;; Fractional multiply
357
358(define_insn "mulv2hqv2sq3_VARIANT_"
359  [(_SET_ _OBRK_(match_operand:_MV2SQ 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
360        (ss_mult:V2SQ
361	 (fract_convert:V2SQ
362	  (match_operand:V2HQ 1 "register_operand" "%a,b,?a,?b"))
363	 (fract_convert:V2SQ
364	  (match_operand:V2HQ 2 "register_operand" "a,b,b,a")))_CBRK_)]
365  ""
366  "%|%.\\tsmpy2\\t%$\\t%1, %2, %_MODk_0"
367  [(set_attr "type" "mpy4")
368   (set_attr "units" "m")
369   (set_attr "cross" "n,n,y,y")])
370
371(define_insn "mulhqsq3_VARIANT_"
372  [(_SET_ _OBRK_(match_operand:_MSQ 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
373        (ss_mult:SQ
374	 (fract_convert:SQ
375	  (match_operand:HQ 1 "register_operand" "%a,b,?a,?b"))
376	 (fract_convert:SQ
377	  (match_operand:HQ 2 "register_operand" "a,b,b,a")))_CBRK_)]
378  ""
379  "%|%.\\tsmpy\\t%$\\t%1, %2, %_MODk_0"
380  [(set_attr "type" "mpy2")
381   (set_attr "units" "m")
382   (set_attr "cross" "n,n,y,y")])
383
384(define_insn "mulhqsq3_lh_VARIANT_"
385  [(_SET_ _OBRK_(match_operand:_MSQ 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
386        (ss_mult:SQ
387	 (fract_convert:SQ
388	  (match_operand:HQ 1 "register_operand" "a,b,?a,?b"))
389	 (fract_convert:SQ
390	  (truncate:HQ (match_operand:SQ 2 "register_operand" "a,b,b,a"))))_CBRK_)]
391  ""
392  "%|%.\\tsmpylh\\t%$\\t%1, %2, %_MODk_0"
393  [(set_attr "type" "mpy2")
394   (set_attr "units" "m")
395   (set_attr "cross" "n,n,y,y")])
396
397(define_insn "mulhqsq3_hl_VARIANT_"
398  [(_SET_ _OBRK_(match_operand:_MSQ 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
399        (ss_mult:SQ
400	 (fract_convert:SQ
401	  (truncate:HQ (match_operand:SQ 1 "register_operand" "a,b,b,a")))
402	 (fract_convert:SQ
403	  (match_operand:HQ 2 "register_operand" "a,b,b,a")))_CBRK_)]
404  ""
405  "%|%.\\tsmpyhl\\t%$\\t%1, %2, %_MODk_0"
406  [(set_attr "type" "mpy2")
407   (set_attr "units" "m")
408   (set_attr "cross" "n,n,y,y")])
409
410(define_insn "mulhqsq3_hh_VARIANT_"
411  [(_SET_ _OBRK_(match_operand:_MSQ 0 "_DESTOPERAND_" "=_A_,_B_,_A_,_B_")
412        (ss_mult:SQ
413	 (fract_convert:SQ
414	  (truncate:HQ (match_operand:SQ 1 "register_operand" "a,b,b,a")))
415	 (fract_convert:SQ
416	  (truncate:HQ (match_operand:SQ 2 "register_operand" "a,b,b,a"))))_CBRK_)]
417  ""
418  "%|%.\\tsmpyh\\t%$\\t%1, %2, %_MODk_0"
419  [(set_attr "type" "mpy2")
420   (set_attr "units" "m")
421   (set_attr "cross" "n,n,y,y")])
422