1;; Matrix-Multiply Assist (MMA) patterns.
2;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
3;; Contributed by Peter Bergner <bergner@linux.ibm.com> and
4;;		  Michael Meissner <meissner@linux.ibm.com>
5;;
6;; This file is part of GCC.
7;;
8;; GCC is free software; you can redistribute it and/or modify it
9;; under the terms of the GNU General Public License as published
10;; by the Free Software Foundation; either version 3, or (at your
11;; option) any later version.
12;;
13;; GCC is distributed in the hope that it will be useful, but WITHOUT
14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16;; License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.
21
22;; The MMA patterns use the multi-register XOmode and OOmode opaque
23;; modes to implement the target specific __vector_quad and
24;; __vector_pair types that the MMA built-in functions reference.  We
25;; use OPAQUE_MODE to prevent anything from trying to open them up.
26
27(define_constants [(MAX_MMA_OPERANDS 7)])
28
29;; Constants for creating unspecs
30
31(define_c_enum "unspec"
32  [UNSPEC_MMA_ASSEMBLE
33   UNSPEC_MMA_EXTRACT
34   UNSPEC_MMA_PMXVBF16GER2
35   UNSPEC_MMA_PMXVBF16GER2NN
36   UNSPEC_MMA_PMXVBF16GER2NP
37   UNSPEC_MMA_PMXVBF16GER2PN
38   UNSPEC_MMA_PMXVBF16GER2PP
39   UNSPEC_MMA_PMXVF16GER2
40   UNSPEC_MMA_PMXVF16GER2NN
41   UNSPEC_MMA_PMXVF16GER2NP
42   UNSPEC_MMA_PMXVF16GER2PN
43   UNSPEC_MMA_PMXVF16GER2PP
44   UNSPEC_MMA_PMXVF32GER
45   UNSPEC_MMA_PMXVF32GERNN
46   UNSPEC_MMA_PMXVF32GERNP
47   UNSPEC_MMA_PMXVF32GERPN
48   UNSPEC_MMA_PMXVF32GERPP
49   UNSPEC_MMA_PMXVF64GER
50   UNSPEC_MMA_PMXVF64GERNN
51   UNSPEC_MMA_PMXVF64GERNP
52   UNSPEC_MMA_PMXVF64GERPN
53   UNSPEC_MMA_PMXVF64GERPP
54   UNSPEC_MMA_PMXVI16GER2
55   UNSPEC_MMA_PMXVI16GER2PP
56   UNSPEC_MMA_PMXVI16GER2S
57   UNSPEC_MMA_PMXVI16GER2SPP
58   UNSPEC_MMA_PMXVI4GER8
59   UNSPEC_MMA_PMXVI4GER8PP
60   UNSPEC_MMA_PMXVI8GER4
61   UNSPEC_MMA_PMXVI8GER4PP
62   UNSPEC_MMA_PMXVI8GER4SPP
63   UNSPEC_MMA_XVBF16GER2
64   UNSPEC_MMA_XVBF16GER2NN
65   UNSPEC_MMA_XVBF16GER2NP
66   UNSPEC_MMA_XVBF16GER2PN
67   UNSPEC_MMA_XVBF16GER2PP
68   UNSPEC_MMA_XVF16GER2
69   UNSPEC_MMA_XVF16GER2NN
70   UNSPEC_MMA_XVF16GER2NP
71   UNSPEC_MMA_XVF16GER2PN
72   UNSPEC_MMA_XVF16GER2PP
73   UNSPEC_MMA_XVF32GER
74   UNSPEC_MMA_XVF32GERNN
75   UNSPEC_MMA_XVF32GERNP
76   UNSPEC_MMA_XVF32GERPN
77   UNSPEC_MMA_XVF32GERPP
78   UNSPEC_MMA_XVF64GER
79   UNSPEC_MMA_XVF64GERNN
80   UNSPEC_MMA_XVF64GERNP
81   UNSPEC_MMA_XVF64GERPN
82   UNSPEC_MMA_XVF64GERPP
83   UNSPEC_MMA_XVI16GER2
84   UNSPEC_MMA_XVI16GER2PP
85   UNSPEC_MMA_XVI16GER2S
86   UNSPEC_MMA_XVI16GER2SPP
87   UNSPEC_MMA_XVI4GER8
88   UNSPEC_MMA_XVI4GER8PP
89   UNSPEC_MMA_XVI8GER4
90   UNSPEC_MMA_XVI8GER4PP
91   UNSPEC_MMA_XVI8GER4SPP
92   UNSPEC_MMA_XXMFACC
93   UNSPEC_MMA_XXMTACC
94  ])
95
96(define_c_enum "unspecv"
97  [UNSPECV_MMA_XXSETACCZ
98  ])
99
100;; MMA instructions with 1 accumulator argument
101(define_int_iterator MMA_ACC		[UNSPEC_MMA_XXMFACC
102					 UNSPEC_MMA_XXMTACC])
103
104;; MMA instructions with 2 vector arguments
105(define_int_iterator MMA_VV		[UNSPEC_MMA_XVI4GER8
106					 UNSPEC_MMA_XVI8GER4
107					 UNSPEC_MMA_XVI16GER2
108					 UNSPEC_MMA_XVI16GER2S
109					 UNSPEC_MMA_XVF16GER2
110					 UNSPEC_MMA_XVBF16GER2
111					 UNSPEC_MMA_XVF32GER])
112
113;; MMA instructions with 1 accumulator and 2 vector arguments
114(define_int_iterator MMA_AVV		[UNSPEC_MMA_XVI4GER8PP
115					 UNSPEC_MMA_XVI8GER4PP
116					 UNSPEC_MMA_XVI8GER4SPP
117					 UNSPEC_MMA_XVI16GER2PP
118					 UNSPEC_MMA_XVI16GER2SPP
119					 UNSPEC_MMA_XVF16GER2PP
120					 UNSPEC_MMA_XVF16GER2PN
121					 UNSPEC_MMA_XVF16GER2NP
122					 UNSPEC_MMA_XVF16GER2NN
123					 UNSPEC_MMA_XVBF16GER2PP
124					 UNSPEC_MMA_XVBF16GER2PN
125					 UNSPEC_MMA_XVBF16GER2NP
126					 UNSPEC_MMA_XVBF16GER2NN
127					 UNSPEC_MMA_XVF32GERPP
128					 UNSPEC_MMA_XVF32GERPN
129					 UNSPEC_MMA_XVF32GERNP
130					 UNSPEC_MMA_XVF32GERNN])
131
132;; MMA instructions with 1 vector pair and 1 vector arguments
133(define_int_iterator MMA_PV		[UNSPEC_MMA_XVF64GER])
134
135;; MMA instructions with 1 accumulator, 1 vector pair and 1 vector arguments
136(define_int_iterator MMA_APV		[UNSPEC_MMA_XVF64GERPP
137					 UNSPEC_MMA_XVF64GERPN
138					 UNSPEC_MMA_XVF64GERNP
139					 UNSPEC_MMA_XVF64GERNN])
140
141;; MMA instructions with 2 vector, 2 4-bit and 1 8-bit arguments
142(define_int_iterator MMA_VVI4I4I8	[UNSPEC_MMA_PMXVI4GER8])
143
144;; MMA instructions with 1 accumulator, 2 vector, 2 4-bit and 1 8-bit arguments
145(define_int_iterator MMA_AVVI4I4I8	[UNSPEC_MMA_PMXVI4GER8PP])
146
147;; MMA instructions with 2 vector, 2 4-bit and 1 2-bit arguments
148(define_int_iterator MMA_VVI4I4I2	[UNSPEC_MMA_PMXVI16GER2
149					 UNSPEC_MMA_PMXVI16GER2S
150					 UNSPEC_MMA_PMXVF16GER2
151					 UNSPEC_MMA_PMXVBF16GER2])
152
153;; MMA instructions with 1 accumulator, 2 vector, 2 4-bit and 1 2-bit arguments
154(define_int_iterator MMA_AVVI4I4I2	[UNSPEC_MMA_PMXVI16GER2PP
155					 UNSPEC_MMA_PMXVI16GER2SPP
156					 UNSPEC_MMA_PMXVF16GER2PP
157					 UNSPEC_MMA_PMXVF16GER2PN
158					 UNSPEC_MMA_PMXVF16GER2NP
159					 UNSPEC_MMA_PMXVF16GER2NN
160					 UNSPEC_MMA_PMXVBF16GER2PP
161					 UNSPEC_MMA_PMXVBF16GER2PN
162					 UNSPEC_MMA_PMXVBF16GER2NP
163					 UNSPEC_MMA_PMXVBF16GER2NN])
164
165;; MMA instructions with 2 vector and 2 4-bit arguments
166(define_int_iterator MMA_VVI4I4		[UNSPEC_MMA_PMXVF32GER])
167
168;; MMA instructions with 1 accumulator, 2 vector and 2 4-bit arguments
169(define_int_iterator MMA_AVVI4I4	[UNSPEC_MMA_PMXVF32GERPP
170					 UNSPEC_MMA_PMXVF32GERPN
171					 UNSPEC_MMA_PMXVF32GERNP
172					 UNSPEC_MMA_PMXVF32GERNN])
173
174;; MMA instructions with 2 vector, 1 4-bit and 1 2-bit arguments
175(define_int_iterator MMA_PVI4I2		[UNSPEC_MMA_PMXVF64GER])
176
177;; MMA instructions with 1 accumulator, 2 vector, 1 4-bit and 1 2-bit arguments
178(define_int_iterator MMA_APVI4I2	[UNSPEC_MMA_PMXVF64GERPP
179					 UNSPEC_MMA_PMXVF64GERPN
180					 UNSPEC_MMA_PMXVF64GERNP
181					 UNSPEC_MMA_PMXVF64GERNN])
182
183;; MMA instructions with 2 vector and 3 4-bit arguments
184(define_int_iterator MMA_VVI4I4I4	[UNSPEC_MMA_PMXVI8GER4])
185
186;; MMA instructions with 1 accumulator, 2 vector and 3 4-bit arguments
187(define_int_iterator MMA_AVVI4I4I4	[UNSPEC_MMA_PMXVI8GER4PP
188					 UNSPEC_MMA_PMXVI8GER4SPP])
189
190(define_int_attr acc		[(UNSPEC_MMA_XXMFACC		"xxmfacc")
191				 (UNSPEC_MMA_XXMTACC		"xxmtacc")])
192
193(define_int_attr vv		[(UNSPEC_MMA_XVI4GER8		"xvi4ger8")
194				 (UNSPEC_MMA_XVI8GER4		"xvi8ger4")
195				 (UNSPEC_MMA_XVI16GER2		"xvi16ger2")
196				 (UNSPEC_MMA_XVI16GER2S		"xvi16ger2s")
197				 (UNSPEC_MMA_XVF16GER2		"xvf16ger2")
198				 (UNSPEC_MMA_XVBF16GER2		"xvbf16ger2")
199				 (UNSPEC_MMA_XVF32GER		"xvf32ger")])
200
201(define_int_attr avv		[(UNSPEC_MMA_XVI4GER8PP		"xvi4ger8pp")
202				 (UNSPEC_MMA_XVI8GER4PP		"xvi8ger4pp")
203				 (UNSPEC_MMA_XVI8GER4SPP	"xvi8ger4spp")
204				 (UNSPEC_MMA_XVI16GER2PP	"xvi16ger2pp")
205				 (UNSPEC_MMA_XVI16GER2SPP	"xvi16ger2spp")
206				 (UNSPEC_MMA_XVF16GER2PP	"xvf16ger2pp")
207				 (UNSPEC_MMA_XVF16GER2PN	"xvf16ger2pn")
208				 (UNSPEC_MMA_XVF16GER2NP	"xvf16ger2np")
209				 (UNSPEC_MMA_XVF16GER2NN	"xvf16ger2nn")
210				 (UNSPEC_MMA_XVBF16GER2PP	"xvbf16ger2pp")
211				 (UNSPEC_MMA_XVBF16GER2PN	"xvbf16ger2pn")
212				 (UNSPEC_MMA_XVBF16GER2NP	"xvbf16ger2np")
213				 (UNSPEC_MMA_XVBF16GER2NN	"xvbf16ger2nn")
214				 (UNSPEC_MMA_XVF32GERPP		"xvf32gerpp")
215				 (UNSPEC_MMA_XVF32GERPN		"xvf32gerpn")
216				 (UNSPEC_MMA_XVF32GERNP		"xvf32gernp")
217				 (UNSPEC_MMA_XVF32GERNN		"xvf32gernn")])
218
219(define_int_attr pv		[(UNSPEC_MMA_XVF64GER		"xvf64ger")])
220
221(define_int_attr apv		[(UNSPEC_MMA_XVF64GERPP		"xvf64gerpp")
222				 (UNSPEC_MMA_XVF64GERPN		"xvf64gerpn")
223				 (UNSPEC_MMA_XVF64GERNP		"xvf64gernp")
224				 (UNSPEC_MMA_XVF64GERNN		"xvf64gernn")])
225
226(define_int_attr vvi4i4i8	[(UNSPEC_MMA_PMXVI4GER8		"pmxvi4ger8")])
227
228(define_int_attr avvi4i4i8	[(UNSPEC_MMA_PMXVI4GER8PP	"pmxvi4ger8pp")])
229
230(define_int_attr vvi4i4i2	[(UNSPEC_MMA_PMXVI16GER2	"pmxvi16ger2")
231				 (UNSPEC_MMA_PMXVI16GER2S	"pmxvi16ger2s")
232				 (UNSPEC_MMA_PMXVF16GER2	"pmxvf16ger2")
233				 (UNSPEC_MMA_PMXVBF16GER2	"pmxvbf16ger2")])
234
235(define_int_attr avvi4i4i2	[(UNSPEC_MMA_PMXVI16GER2PP	"pmxvi16ger2pp")
236				 (UNSPEC_MMA_PMXVI16GER2SPP	"pmxvi16ger2spp")
237				 (UNSPEC_MMA_PMXVF16GER2PP	"pmxvf16ger2pp")
238				 (UNSPEC_MMA_PMXVF16GER2PN	"pmxvf16ger2pn")
239				 (UNSPEC_MMA_PMXVF16GER2NP	"pmxvf16ger2np")
240				 (UNSPEC_MMA_PMXVF16GER2NN	"pmxvf16ger2nn")
241				 (UNSPEC_MMA_PMXVBF16GER2PP	"pmxvbf16ger2pp")
242				 (UNSPEC_MMA_PMXVBF16GER2PN	"pmxvbf16ger2pn")
243				 (UNSPEC_MMA_PMXVBF16GER2NP	"pmxvbf16ger2np")
244				 (UNSPEC_MMA_PMXVBF16GER2NN	"pmxvbf16ger2nn")])
245
246(define_int_attr vvi4i4		[(UNSPEC_MMA_PMXVF32GER		"pmxvf32ger")])
247
248(define_int_attr avvi4i4	[(UNSPEC_MMA_PMXVF32GERPP	"pmxvf32gerpp")
249				 (UNSPEC_MMA_PMXVF32GERPN	"pmxvf32gerpn")
250				 (UNSPEC_MMA_PMXVF32GERNP	"pmxvf32gernp")
251				 (UNSPEC_MMA_PMXVF32GERNN	"pmxvf32gernn")])
252
253(define_int_attr pvi4i2		[(UNSPEC_MMA_PMXVF64GER		"pmxvf64ger")])
254
255(define_int_attr apvi4i2	[(UNSPEC_MMA_PMXVF64GERPP	"pmxvf64gerpp")
256				 (UNSPEC_MMA_PMXVF64GERPN	"pmxvf64gerpn")
257				 (UNSPEC_MMA_PMXVF64GERNP	"pmxvf64gernp")
258				 (UNSPEC_MMA_PMXVF64GERNN	"pmxvf64gernn")])
259
260(define_int_attr vvi4i4i4	[(UNSPEC_MMA_PMXVI8GER4		"pmxvi8ger4")])
261
262(define_int_attr avvi4i4i4	[(UNSPEC_MMA_PMXVI8GER4PP	"pmxvi8ger4pp")
263				 (UNSPEC_MMA_PMXVI8GER4SPP	"pmxvi8ger4spp")])
264
265
266;; Vector pair support.  OOmode can only live in VSRs.
267(define_expand "movoo"
268  [(set (match_operand:OO 0 "nonimmediate_operand")
269	(match_operand:OO 1 "input_operand"))]
270  "TARGET_MMA"
271{
272  rs6000_emit_move (operands[0], operands[1], OOmode);
273  DONE;
274})
275
276(define_insn_and_split "*movoo"
277  [(set (match_operand:OO 0 "nonimmediate_operand" "=wa,m,wa")
278	(match_operand:OO 1 "input_operand" "m,wa,wa"))]
279  "TARGET_MMA
280   && (gpc_reg_operand (operands[0], OOmode)
281       || gpc_reg_operand (operands[1], OOmode))"
282  "@
283   lxvp%X1 %x0,%1
284   stxvp%X0 %x1,%0
285   #"
286  "&& reload_completed
287   && (!MEM_P (operands[0]) && !MEM_P (operands[1]))"
288  [(const_int 0)]
289{
290  rs6000_split_multireg_move (operands[0], operands[1]);
291  DONE;
292}
293  [(set_attr "type" "vecload,vecstore,veclogical")
294   (set_attr "size" "256")
295   (set_attr "length" "*,*,8")])
296
297
298;; Vector quad support.  XOmode can only live in FPRs.
299(define_expand "movxo"
300  [(set (match_operand:XO 0 "nonimmediate_operand")
301	(match_operand:XO 1 "input_operand"))]
302  "TARGET_MMA"
303{
304  rs6000_emit_move (operands[0], operands[1], XOmode);
305  DONE;
306})
307
308(define_insn_and_split "*movxo"
309  [(set (match_operand:XO 0 "nonimmediate_operand" "=d,m,d")
310	(match_operand:XO 1 "input_operand" "m,d,d"))]
311  "TARGET_MMA
312   && (gpc_reg_operand (operands[0], XOmode)
313       || gpc_reg_operand (operands[1], XOmode))"
314  "@
315   #
316   #
317   #"
318  "&& reload_completed"
319  [(const_int 0)]
320{
321  rs6000_split_multireg_move (operands[0], operands[1]);
322  DONE;
323}
324  [(set_attr "type" "vecload,vecstore,veclogical")
325   (set_attr "length" "*,*,16")
326   (set_attr "max_prefixed_insns" "2,2,*")])
327
328(define_expand "vsx_assemble_pair"
329  [(match_operand:OO 0 "vsx_register_operand")
330   (match_operand:V16QI 1 "mma_assemble_input_operand")
331   (match_operand:V16QI 2 "mma_assemble_input_operand")]
332  "TARGET_MMA"
333{
334  rtx src = gen_rtx_UNSPEC (OOmode,
335			    gen_rtvec (2, operands[1], operands[2]),
336			    UNSPEC_MMA_ASSEMBLE);
337  emit_move_insn (operands[0], src);
338  DONE;
339})
340
341;; We cannot update the two output registers atomically, so mark the output
342;; as an early clobber so we don't accidentally clobber the input operands.  */
343
344(define_insn_and_split "*vsx_assemble_pair"
345  [(set (match_operand:OO 0 "vsx_register_operand" "=&wa")
346	(unspec:OO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
347		    (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")]
348		    UNSPEC_MMA_ASSEMBLE))]
349  "TARGET_MMA"
350  "#"
351  "&& reload_completed"
352  [(const_int 0)]
353{
354  rtx src = gen_rtx_UNSPEC (OOmode,
355			    gen_rtvec (2, operands[1], operands[2]),
356			    UNSPEC_MMA_ASSEMBLE);
357  rs6000_split_multireg_move (operands[0], src);
358  DONE;
359})
360
361(define_expand "vsx_disassemble_pair"
362  [(match_operand:V16QI 0 "mma_disassemble_output_operand")
363   (match_operand:OO 1 "vsx_register_operand")
364   (match_operand 2 "const_0_to_1_operand")]
365  "TARGET_MMA"
366{
367  rtx src;
368  int regoff = INTVAL (operands[2]);
369  src = gen_rtx_UNSPEC (V16QImode,
370			gen_rtvec (2, operands[1], GEN_INT (regoff)),
371			UNSPEC_MMA_EXTRACT);
372  emit_move_insn (operands[0], src);
373  DONE;
374})
375
376(define_insn_and_split "*vsx_disassemble_pair"
377  [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa")
378       (unspec:V16QI [(match_operand:OO 1 "vsx_register_operand" "wa")
379		      (match_operand 2 "const_0_to_1_operand")]
380		      UNSPEC_MMA_EXTRACT))]
381  "TARGET_MMA
382   && vsx_register_operand (operands[1], OOmode)"
383  "#"
384  "&& reload_completed"
385  [(const_int 0)]
386{
387  int reg = REGNO (operands[1]);
388  int regoff = INTVAL (operands[2]);
389  rtx src = gen_rtx_REG (V16QImode, reg + regoff);
390  emit_move_insn (operands[0], src);
391  DONE;
392})
393
394(define_expand "mma_assemble_acc"
395  [(match_operand:XO 0 "fpr_reg_operand")
396   (match_operand:V16QI 1 "mma_assemble_input_operand")
397   (match_operand:V16QI 2 "mma_assemble_input_operand")
398   (match_operand:V16QI 3 "mma_assemble_input_operand")
399   (match_operand:V16QI 4 "mma_assemble_input_operand")]
400  "TARGET_MMA"
401{
402  rtx src = gen_rtx_UNSPEC (XOmode,
403			    gen_rtvec (4, operands[1], operands[2],
404				       operands[3], operands[4]),
405			    UNSPEC_MMA_ASSEMBLE);
406  emit_move_insn (operands[0], src);
407  DONE;
408})
409
410;; We cannot update the four output registers atomically, so mark the output
411;; as an early clobber so we don't accidentally clobber the input operands.  */
412
413(define_insn_and_split "*mma_assemble_acc"
414  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
415	(unspec:XO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
416		    (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")
417		    (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa")
418		    (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")]
419		    UNSPEC_MMA_ASSEMBLE))]
420  "TARGET_MMA
421   && fpr_reg_operand (operands[0], XOmode)"
422  "#"
423  "&& reload_completed"
424  [(const_int 0)]
425{
426  rtx src = gen_rtx_UNSPEC (XOmode,
427			    gen_rtvec (4, operands[1], operands[2],
428				       operands[3], operands[4]),
429			    UNSPEC_MMA_ASSEMBLE);
430  rs6000_split_multireg_move (operands[0], src);
431  DONE;
432})
433
434(define_expand "mma_disassemble_acc"
435  [(match_operand:V16QI 0 "mma_disassemble_output_operand")
436   (match_operand:XO 1 "fpr_reg_operand")
437   (match_operand 2 "const_0_to_3_operand")]
438  "TARGET_MMA"
439{
440  rtx src;
441  int regoff = INTVAL (operands[2]);
442  src = gen_rtx_UNSPEC (V16QImode,
443			gen_rtvec (2, operands[1], GEN_INT (regoff)),
444			UNSPEC_MMA_EXTRACT);
445  emit_move_insn (operands[0], src);
446  DONE;
447})
448
449(define_insn_and_split "*mma_disassemble_acc"
450  [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa")
451       (unspec:V16QI [(match_operand:XO 1 "fpr_reg_operand" "d")
452		      (match_operand 2 "const_0_to_3_operand")]
453		      UNSPEC_MMA_EXTRACT))]
454  "TARGET_MMA
455   && fpr_reg_operand (operands[1], XOmode)"
456  "#"
457  "&& reload_completed"
458  [(const_int 0)]
459{
460  int reg = REGNO (operands[1]);
461  int regoff = INTVAL (operands[2]);
462  rtx src = gen_rtx_REG (V16QImode, reg + regoff);
463  emit_move_insn (operands[0], src);
464  DONE;
465})
466
467;; MMA instructions that do not use their accumulators as an input, still
468;; must not allow their vector operands to overlap the registers used by
469;; the accumulator.  We enforce this by marking the output as early clobber.
470
471(define_insn "mma_<acc>"
472  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
473	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")]
474		    MMA_ACC))]
475  "TARGET_MMA"
476  "<acc> %A0"
477  [(set_attr "type" "mma")])
478
479;; We can't have integer constants in XOmode so we wrap this in an
480;; UNSPEC_VOLATILE.
481
482(define_insn "mma_xxsetaccz"
483  [(set (match_operand:XO 0 "fpr_reg_operand" "=d")
484	(unspec_volatile:XO [(const_int 0)]
485			    UNSPECV_MMA_XXSETACCZ))]
486  "TARGET_MMA"
487  "xxsetaccz %A0"
488  [(set_attr "type" "mma")])
489
490(define_insn "mma_<vv>"
491  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
492	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
493		    (match_operand:V16QI 2 "vsx_register_operand" "wa")]
494		    MMA_VV))]
495  "TARGET_MMA"
496  "<vv> %A0,%x1,%x2"
497  [(set_attr "type" "mma")])
498
499(define_insn "mma_<avv>"
500  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
501	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
502		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
503		    (match_operand:V16QI 3 "vsx_register_operand" "wa")]
504		    MMA_AVV))]
505  "TARGET_MMA"
506  "<avv> %A0,%x2,%x3"
507  [(set_attr "type" "mma")])
508
509(define_insn "mma_<pv>"
510  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
511	(unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa")
512		    (match_operand:V16QI 2 "vsx_register_operand" "wa")]
513		    MMA_PV))]
514  "TARGET_MMA"
515  "<pv> %A0,%x1,%x2"
516  [(set_attr "type" "mma")])
517
518(define_insn "mma_<apv>"
519  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
520	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
521		    (match_operand:OO 2 "vsx_register_operand" "wa")
522		    (match_operand:V16QI 3 "vsx_register_operand" "wa")]
523		    MMA_APV))]
524  "TARGET_MMA"
525  "<apv> %A0,%x2,%x3"
526  [(set_attr "type" "mma")])
527
528(define_insn "mma_<vvi4i4i8>"
529  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
530	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
531		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
532		    (match_operand:SI 3 "const_0_to_15_operand" "n")
533		    (match_operand:SI 4 "const_0_to_15_operand" "n")
534		    (match_operand:SI 5 "u8bit_cint_operand" "n")]
535		    MMA_VVI4I4I8))]
536  "TARGET_MMA"
537  "<vvi4i4i8> %A0,%x1,%x2,%3,%4,%5"
538  [(set_attr "type" "mma")
539   (set_attr "prefixed" "yes")])
540
541(define_insn "mma_<avvi4i4i8>"
542  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
543	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
544		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
545		    (match_operand:V16QI 3 "vsx_register_operand" "wa")
546		    (match_operand:SI 4 "const_0_to_15_operand" "n")
547		    (match_operand:SI 5 "const_0_to_15_operand" "n")
548		    (match_operand:SI 6 "u8bit_cint_operand" "n")]
549		    MMA_AVVI4I4I8))]
550  "TARGET_MMA"
551  "<avvi4i4i8> %A0,%x2,%x3,%4,%5,%6"
552  [(set_attr "type" "mma")
553   (set_attr "prefixed" "yes")])
554
555(define_insn "mma_<vvi4i4i2>"
556  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
557	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
558		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
559		    (match_operand:SI 3 "const_0_to_15_operand" "n")
560		    (match_operand:SI 4 "const_0_to_15_operand" "n")
561		    (match_operand:SI 5 "const_0_to_3_operand" "n")]
562		    MMA_VVI4I4I2))]
563  "TARGET_MMA"
564  "<vvi4i4i2> %A0,%x1,%x2,%3,%4,%5"
565  [(set_attr "type" "mma")
566   (set_attr "prefixed" "yes")])
567
568(define_insn "mma_<avvi4i4i2>"
569  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
570	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
571		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
572		    (match_operand:V16QI 3 "vsx_register_operand" "wa")
573		    (match_operand:SI 4 "const_0_to_15_operand" "n")
574		    (match_operand:SI 5 "const_0_to_15_operand" "n")
575		    (match_operand:SI 6 "const_0_to_3_operand" "n")]
576		    MMA_AVVI4I4I2))]
577  "TARGET_MMA"
578  "<avvi4i4i2> %A0,%x2,%x3,%4,%5,%6"
579  [(set_attr "type" "mma")
580   (set_attr "prefixed" "yes")])
581
582(define_insn "mma_<vvi4i4>"
583  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
584	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
585		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
586		    (match_operand:SI 3 "const_0_to_15_operand" "n")
587		    (match_operand:SI 4 "const_0_to_15_operand" "n")]
588		    MMA_VVI4I4))]
589  "TARGET_MMA"
590  "<vvi4i4> %A0,%x1,%x2,%3,%4"
591  [(set_attr "type" "mma")
592   (set_attr "prefixed" "yes")])
593
594(define_insn "mma_<avvi4i4>"
595  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
596	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
597		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
598		    (match_operand:V16QI 3 "vsx_register_operand" "wa")
599		    (match_operand:SI 4 "const_0_to_15_operand" "n")
600		    (match_operand:SI 5 "const_0_to_15_operand" "n")]
601		    MMA_AVVI4I4))]
602  "TARGET_MMA"
603  "<avvi4i4> %A0,%x2,%x3,%4,%5"
604  [(set_attr "type" "mma")
605   (set_attr "prefixed" "yes")])
606
607(define_insn "mma_<pvi4i2>"
608  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
609	(unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa")
610		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
611		    (match_operand:SI 3 "const_0_to_15_operand" "n")
612		    (match_operand:SI 4 "const_0_to_3_operand" "n")]
613		    MMA_PVI4I2))]
614  "TARGET_MMA"
615  "<pvi4i2> %A0,%x1,%x2,%3,%4"
616  [(set_attr "type" "mma")
617   (set_attr "prefixed" "yes")])
618
619(define_insn "mma_<apvi4i2>"
620  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
621	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
622		    (match_operand:OO 2 "vsx_register_operand" "wa")
623		    (match_operand:V16QI 3 "vsx_register_operand" "wa")
624		    (match_operand:SI 4 "const_0_to_15_operand" "n")
625		    (match_operand:SI 5 "const_0_to_3_operand" "n")]
626		    MMA_APVI4I2))]
627  "TARGET_MMA"
628  "<apvi4i2> %A0,%x2,%x3,%4,%5"
629  [(set_attr "type" "mma")
630   (set_attr "prefixed" "yes")])
631
632(define_insn "mma_<vvi4i4i4>"
633  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
634	(unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
635		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
636		    (match_operand:SI 3 "const_0_to_15_operand" "n")
637		    (match_operand:SI 4 "const_0_to_15_operand" "n")
638		    (match_operand:SI 5 "const_0_to_15_operand" "n")]
639		    MMA_VVI4I4I4))]
640  "TARGET_MMA"
641  "<vvi4i4i4> %A0,%x1,%x2,%3,%4,%5"
642  [(set_attr "type" "mma")
643   (set_attr "prefixed" "yes")])
644
645(define_insn "mma_<avvi4i4i4>"
646  [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
647	(unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
648		    (match_operand:V16QI 2 "vsx_register_operand" "wa")
649		    (match_operand:V16QI 3 "vsx_register_operand" "wa")
650		    (match_operand:SI 4 "const_0_to_15_operand" "n")
651		    (match_operand:SI 5 "const_0_to_15_operand" "n")
652		    (match_operand:SI 6 "const_0_to_15_operand" "n")]
653		    MMA_AVVI4I4I4))]
654  "TARGET_MMA"
655  "<avvi4i4i4> %A0,%x2,%x3,%4,%5,%6"
656  [(set_attr "type" "mma")
657   (set_attr "prefixed" "yes")])
658