* config/nvptx/nvptx.c (nvptx_output_call_insn): Expect hard regs.
[official-gcc.git] / gcc / config / nvptx / nvptx.md
blob565be196b0a5f17e2bd6193b30547c511602b52a
1 ;; Machine description for NVPTX.
2 ;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
3 ;; Contributed by Bernd Schmidt <bernds@codesourcery.com>
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_c_enum "unspec" [
22    UNSPEC_ARG_REG
24    UNSPEC_COPYSIGN
25    UNSPEC_LOG2
26    UNSPEC_EXP2
27    UNSPEC_SIN
28    UNSPEC_COS
30    UNSPEC_FPINT_FLOOR
31    UNSPEC_FPINT_BTRUNC
32    UNSPEC_FPINT_CEIL
33    UNSPEC_FPINT_NEARBYINT
35    UNSPEC_BITREV
37    UNSPEC_ALLOCA
39    UNSPEC_DIM_SIZE
41    UNSPEC_BIT_CONV
43    UNSPEC_SHUFFLE
44    UNSPEC_BR_UNIFIED
47 (define_c_enum "unspecv" [
48    UNSPECV_LOCK
49    UNSPECV_CAS
50    UNSPECV_XCHG
51    UNSPECV_BARSYNC
52    UNSPECV_DIM_POS
54    UNSPECV_FORK
55    UNSPECV_FORKED
56    UNSPECV_JOINING
57    UNSPECV_JOIN
60 (define_attr "subregs_ok" "false,true"
61   (const_string "false"))
63 ;; The nvptx operand predicates, in general, don't permit subregs and
64 ;; only literal constants, which differ from the generic ones, which
65 ;; permit subregs and symbolc constants (as appropriate)
66 (define_predicate "nvptx_register_operand"
67   (match_code "reg")
69   return register_operand (op, mode);
72 (define_predicate "nvptx_nonimmediate_operand"
73   (match_code "mem,reg")
75   return (REG_P (op) ? register_operand (op, mode)
76           : memory_operand (op, mode));
79 (define_predicate "nvptx_nonmemory_operand"
80   (match_code "reg,const_int,const_double")
82   return (REG_P (op) ? register_operand (op, mode)
83           : immediate_operand (op, mode));
86 (define_predicate "const0_operand"
87   (and (match_code "const_int")
88        (match_test "op == const0_rtx")))
90 ;; True if this operator is valid for predication.
91 (define_predicate "predicate_operator"
92   (match_code "eq,ne"))
94 (define_predicate "ne_operator"
95   (match_code "ne"))
97 (define_predicate "nvptx_comparison_operator"
98   (match_code "eq,ne,le,ge,lt,gt,leu,geu,ltu,gtu"))
100 (define_predicate "nvptx_float_comparison_operator"
101   (match_code "eq,ne,le,ge,lt,gt,uneq,unle,unge,unlt,ungt,unordered,ordered"))
103 ;; Test for a valid operand for a call instruction.
104 (define_predicate "call_insn_operand"
105   (match_code "symbol_ref,reg")
107   return REG_P (op) || SYMBOL_REF_FUNCTION_P (op);
110 ;; Return true if OP is a call with parallel USEs of the argument
111 ;; pseudos.
112 (define_predicate "call_operation"
113   (match_code "parallel")
115   int arg_end = XVECLEN (op, 0);
117   for (int i = 1; i < arg_end; i++)
118     {
119       rtx elt = XVECEXP (op, 0, i);
121       if (GET_CODE (elt) != USE || !REG_P (XEXP (elt, 0)))
122         return false;
123     }
124   return true;
127 (define_constraint "P0"
128   "An integer with the value 0."
129   (and (match_code "const_int")
130        (match_test "ival == 0")))
132 (define_constraint "P1"
133   "An integer with the value 1."
134   (and (match_code "const_int")
135        (match_test "ival == 1")))
137 (define_constraint "Pn"
138   "An integer with the value -1."
139   (and (match_code "const_int")
140        (match_test "ival == -1")))
142 (define_constraint "R"
143   "A pseudo register."
144   (match_code "reg"))
146 (define_constraint "Ia"
147   "Any integer constant."
148   (and (match_code "const_int") (match_test "true")))
150 (define_mode_iterator QHSDISDFM [QI HI SI DI SF DF])
151 (define_mode_iterator QHSDIM [QI HI SI DI])
152 (define_mode_iterator HSDIM [HI SI DI])
153 (define_mode_iterator BHSDIM [BI HI SI DI])
154 (define_mode_iterator SDIM [SI DI])
155 (define_mode_iterator SDISDFM [SI DI SF DF])
156 (define_mode_iterator QHIM [QI HI])
157 (define_mode_iterator QHSIM [QI HI SI])
158 (define_mode_iterator SDFM [SF DF])
159 (define_mode_iterator SDCM [SC DC])
160 (define_mode_iterator BITS [SI SF])
161 (define_mode_iterator BITD [DI DF])
163 ;; This mode iterator allows :P to be used for patterns that operate on
164 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
165 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
167 ;; We should get away with not defining memory alternatives, since we don't
168 ;; get variables in this mode and pseudos are never spilled.
169 (define_insn "movbi"
170   [(set (match_operand:BI 0 "nvptx_register_operand" "=R,R,R")
171         (match_operand:BI 1 "nvptx_nonmemory_operand" "R,P0,Pn"))]
172   ""
173   "@
174    %.\\tmov%t0\\t%0, %1;
175    %.\\tsetp.eq.u32\\t%0, 1, 0;
176    %.\\tsetp.eq.u32\\t%0, 1, 1;")
178 (define_insn "*mov<mode>_insn"
179   [(set (match_operand:QHSDIM 0 "nonimmediate_operand" "=R,R,m")
180         (match_operand:QHSDIM 1 "general_operand" "Ri,m,R"))]
181   "!MEM_P (operands[0]) || REG_P (operands[1])"
183   if (which_alternative == 1)
184     return "%.\\tld%A1%u1\\t%0, %1;";
185   if (which_alternative == 2)
186     return "%.\\tst%A0%u0\\t%0, %1;";
188   return nvptx_output_mov_insn (operands[0], operands[1]);
190   [(set_attr "subregs_ok" "true")])
192 (define_insn "*mov<mode>_insn"
193   [(set (match_operand:SDFM 0 "nonimmediate_operand" "=R,R,m")
194         (match_operand:SDFM 1 "general_operand" "RF,m,R"))]
195   "!MEM_P (operands[0]) || REG_P (operands[1])"
197   if (which_alternative == 1)
198     return "%.\\tld%A1%u0\\t%0, %1;";
199   if (which_alternative == 2)
200     return "%.\\tst%A0%u1\\t%0, %1;";
202   return nvptx_output_mov_insn (operands[0], operands[1]);
204   [(set_attr "subregs_ok" "true")])
206 (define_insn "load_arg_reg<mode>"
207   [(set (match_operand:QHIM 0 "nvptx_register_operand" "=R")
208         (unspec:QHIM [(match_operand 1 "const_int_operand" "n")]
209                      UNSPEC_ARG_REG))]
210   ""
211   "%.\\tcvt%t0.u32\\t%0, %%ar%1;")
213 (define_insn "load_arg_reg<mode>"
214   [(set (match_operand:SDISDFM 0 "nvptx_register_operand" "=R")
215         (unspec:SDISDFM [(match_operand 1 "const_int_operand" "n")]
216                         UNSPEC_ARG_REG))]
217   ""
218   "%.\\tmov%t0\\t%0, %%ar%1;")
220 (define_expand "mov<mode>"
221   [(set (match_operand:QHSDISDFM 0 "nonimmediate_operand" "")
222         (match_operand:QHSDISDFM 1 "general_operand" ""))]
223   ""
225   if (MEM_P (operands[0]) && !REG_P (operands[1]))
226     {
227       rtx tmp = gen_reg_rtx (<MODE>mode);
228       emit_move_insn (tmp, operands[1]);
229       emit_move_insn (operands[0], tmp);
230       DONE;
231     }
234 (define_insn "zero_extendqihi2"
235   [(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
236         (zero_extend:HI (match_operand:QI 1 "nvptx_nonimmediate_operand" "R,m")))]
237   ""
238   "@
239    %.\\tcvt.u16.u%T1\\t%0, %1;
240    %.\\tld%A1.u8\\t%0, %1;"
241   [(set_attr "subregs_ok" "true")])
243 (define_insn "zero_extend<mode>si2"
244   [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
245         (zero_extend:SI (match_operand:QHIM 1 "nvptx_nonimmediate_operand" "R,m")))]
246   ""
247   "@
248    %.\\tcvt.u32.u%T1\\t%0, %1;
249    %.\\tld%A1.u%T1\\t%0, %1;"
250   [(set_attr "subregs_ok" "true")])
252 (define_insn "zero_extend<mode>di2"
253   [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
254         (zero_extend:DI (match_operand:QHSIM 1 "nvptx_nonimmediate_operand" "R,m")))]
255   ""
256   "@
257    %.\\tcvt.u64.u%T1\\t%0, %1;
258    %.\\tld%A1%u1\\t%0, %1;"
259   [(set_attr "subregs_ok" "true")])
261 (define_insn "extend<mode>si2"
262   [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
263         (sign_extend:SI (match_operand:QHIM 1 "nvptx_nonimmediate_operand" "R,m")))]
264   ""
265   "@
266    %.\\tcvt.s32.s%T1\\t%0, %1;
267    %.\\tld%A1.s%T1\\t%0, %1;"
268   [(set_attr "subregs_ok" "true")])
270 (define_insn "extend<mode>di2"
271   [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
272         (sign_extend:DI (match_operand:QHSIM 1 "nvptx_nonimmediate_operand" "R,m")))]
273   ""
274   "@
275    %.\\tcvt.s64.s%T1\\t%0, %1;
276    %.\\tld%A1.s%T1\\t%0, %1;"
277   [(set_attr "subregs_ok" "true")])
279 (define_insn "trunchiqi2"
280   [(set (match_operand:QI 0 "nvptx_nonimmediate_operand" "=R,m")
281         (truncate:QI (match_operand:HI 1 "nvptx_register_operand" "R,R")))]
282   ""
283   "@
284    %.\\tcvt%t0.u16\\t%0, %1;
285    %.\\tst%A0.u8\\t%0, %1;"
286   [(set_attr "subregs_ok" "true")])
288 (define_insn "truncsi<mode>2"
289   [(set (match_operand:QHIM 0 "nvptx_nonimmediate_operand" "=R,m")
290         (truncate:QHIM (match_operand:SI 1 "nvptx_register_operand" "R,R")))]
291   ""
292   "@
293    %.\\tcvt%t0.u32\\t%0, %1;
294    %.\\tst%A0.u%T0\\t%0, %1;"
295   [(set_attr "subregs_ok" "true")])
297 (define_insn "truncdi<mode>2"
298   [(set (match_operand:QHSIM 0 "nvptx_nonimmediate_operand" "=R,m")
299         (truncate:QHSIM (match_operand:DI 1 "nvptx_register_operand" "R,R")))]
300   ""
301   "@
302    %.\\tcvt%t0.u64\\t%0, %1;
303    %.\\tst%A0.u%T0\\t%0, %1;"
304   [(set_attr "subregs_ok" "true")])
306 ;; Integer arithmetic
308 (define_insn "add<mode>3"
309   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
310         (plus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
311                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
312   ""
313   "%.\\tadd%t0\\t%0, %1, %2;")
315 (define_insn "sub<mode>3"
316   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
317         (minus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
318                      (match_operand:HSDIM 2 "nvptx_register_operand" "R")))]
319   ""
320   "%.\\tsub%t0\\t%0, %1, %2;")
322 (define_insn "mul<mode>3"
323   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
324         (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
325                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
326   ""
327   "%.\\tmul.lo%t0\\t%0, %1, %2;")
329 (define_insn "*mad<mode>3"
330   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
331         (plus:HSDIM (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
332                                 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri"))
333                     (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
334   ""
335   "%.\\tmad.lo%t0\\t%0, %1, %2, %3;")
337 (define_insn "div<mode>3"
338   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
339         (div:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
340                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
341   ""
342   "%.\\tdiv.s%T0\\t%0, %1, %2;")
344 (define_insn "udiv<mode>3"
345   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
346         (udiv:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
347                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
348   ""
349   "%.\\tdiv.u%T0\\t%0, %1, %2;")
351 (define_insn "mod<mode>3"
352   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
353         (mod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
354                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
355   ""
356   "%.\\trem.s%T0\\t%0, %1, %2;")
358 (define_insn "umod<mode>3"
359   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
360         (umod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
361                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
362   ""
363   "%.\\trem.u%T0\\t%0, %1, %2;")
365 (define_insn "smin<mode>3"
366   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
367         (smin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
368                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
369   ""
370   "%.\\tmin.s%T0\\t%0, %1, %2;")
372 (define_insn "umin<mode>3"
373   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
374         (umin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
375                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
376   ""
377   "%.\\tmin.u%T0\\t%0, %1, %2;")
379 (define_insn "smax<mode>3"
380   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
381         (smax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
382                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
383   ""
384   "%.\\tmax.s%T0\\t%0, %1, %2;")
386 (define_insn "umax<mode>3"
387   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
388         (umax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
389                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
390   ""
391   "%.\\tmax.u%T0\\t%0, %1, %2;")
393 (define_insn "abs<mode>2"
394   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
395         (abs:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
396   ""
397   "%.\\tabs.s%T0\\t%0, %1;")
399 (define_insn "neg<mode>2"
400   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
401         (neg:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
402   ""
403   "%.\\tneg.s%T0\\t%0, %1;")
405 (define_insn "one_cmpl<mode>2"
406   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
407         (not:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
408   ""
409   "%.\\tnot.b%T0\\t%0, %1;")
411 (define_insn "bitrev<mode>2"
412   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
413         (unspec:SDIM [(match_operand:SDIM 1 "nvptx_register_operand" "R")]
414                      UNSPEC_BITREV))]
415   ""
416   "%.\\tbrev.b%T0\\t%0, %1;")
418 (define_insn "clz<mode>2"
419   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
420         (clz:SI (match_operand:SDIM 1 "nvptx_register_operand" "R")))]
421   ""
422   "%.\\tclz.b%T1\\t%0, %1;")
424 (define_expand "ctz<mode>2"
425   [(set (match_operand:SI 0 "nvptx_register_operand" "")
426         (ctz:SI (match_operand:SDIM 1 "nvptx_register_operand" "")))]
427   ""
429   rtx tmpreg = gen_reg_rtx (<MODE>mode);
430   emit_insn (gen_bitrev<mode>2 (tmpreg, operands[1]));
431   emit_insn (gen_clz<mode>2 (operands[0], tmpreg));
432   DONE;
435 ;; Shifts
437 (define_insn "ashl<mode>3"
438   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
439         (ashift:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
440                      (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
441   ""
442   "%.\\tshl.b%T0\\t%0, %1, %2;")
444 (define_insn "ashr<mode>3"
445   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
446         (ashiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
447                        (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
448   ""
449   "%.\\tshr.s%T0\\t%0, %1, %2;")
451 (define_insn "lshr<mode>3"
452   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
453         (lshiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
454                        (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
455   ""
456   "%.\\tshr.u%T0\\t%0, %1, %2;")
458 ;; Logical operations
460 (define_insn "and<mode>3"
461   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
462         (and:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
463                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
464   ""
465   "%.\\tand.b%T0\\t%0, %1, %2;")
467 (define_insn "ior<mode>3"
468   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
469         (ior:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
470                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
471   ""
472   "%.\\tor.b%T0\\t%0, %1, %2;")
474 (define_insn "xor<mode>3"
475   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
476         (xor:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
477                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
478   ""
479   "%.\\txor.b%T0\\t%0, %1, %2;")
481 ;; Comparisons and branches
483 (define_insn "*cmp<mode>"
484   [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
485         (match_operator:BI 1 "nvptx_comparison_operator"
486            [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
487             (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
488   ""
489   "%.\\tsetp%c1\\t%0, %2, %3;")
491 (define_insn "*cmp<mode>"
492   [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
493         (match_operator:BI 1 "nvptx_float_comparison_operator"
494            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
495             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
496   ""
497   "%.\\tsetp%c1\\t%0, %2, %3;")
499 (define_insn "jump"
500   [(set (pc)
501         (label_ref (match_operand 0 "" "")))]
502   ""
503   "%.\\tbra\\t%l0;")
505 (define_insn "br_true"
506   [(set (pc)
507         (if_then_else (ne (match_operand:BI 0 "nvptx_register_operand" "R")
508                           (const_int 0))
509                       (label_ref (match_operand 1 "" ""))
510                       (pc)))]
511   ""
512   "%j0\\tbra\\t%l1;")
514 (define_insn "br_false"
515   [(set (pc)
516         (if_then_else (eq (match_operand:BI 0 "nvptx_register_operand" "R")
517                           (const_int 0))
518                       (label_ref (match_operand 1 "" ""))
519                       (pc)))]
520   ""
521   "%J0\\tbra\\t%l1;")
523 ;; unified conditional branch
524 (define_insn "br_true_uni"
525   [(set (pc) (if_then_else
526         (ne (unspec:BI [(match_operand:BI 0 "nvptx_register_operand" "R")]
527                        UNSPEC_BR_UNIFIED) (const_int 0))
528         (label_ref (match_operand 1 "" "")) (pc)))]
529   ""
530   "%j0\\tbra.uni\\t%l1;")
532 (define_insn "br_false_uni"
533   [(set (pc) (if_then_else
534         (eq (unspec:BI [(match_operand:BI 0 "nvptx_register_operand" "R")]
535                        UNSPEC_BR_UNIFIED) (const_int 0))
536         (label_ref (match_operand 1 "" "")) (pc)))]
537   ""
538   "%J0\\tbra.uni\\t%l1;")
540 (define_expand "cbranch<mode>4"
541   [(set (pc)
542         (if_then_else (match_operator 0 "nvptx_comparison_operator"
543                        [(match_operand:HSDIM 1 "nvptx_register_operand" "")
544                         (match_operand:HSDIM 2 "nvptx_register_operand" "")])
545                       (label_ref (match_operand 3 "" ""))
546                       (pc)))]
547   ""
549   rtx t = nvptx_expand_compare (operands[0]);
550   operands[0] = t;
551   operands[1] = XEXP (t, 0);
552   operands[2] = XEXP (t, 1);
555 (define_expand "cbranch<mode>4"
556   [(set (pc)
557         (if_then_else (match_operator 0 "nvptx_float_comparison_operator"
558                        [(match_operand:SDFM 1 "nvptx_register_operand" "")
559                         (match_operand:SDFM 2 "nvptx_register_operand" "")])
560                       (label_ref (match_operand 3 "" ""))
561                       (pc)))]
562   ""
564   rtx t = nvptx_expand_compare (operands[0]);
565   operands[0] = t;
566   operands[1] = XEXP (t, 0);
567   operands[2] = XEXP (t, 1);
570 (define_expand "cbranchbi4"
571   [(set (pc)
572         (if_then_else (match_operator 0 "predicate_operator"
573                        [(match_operand:BI 1 "nvptx_register_operand" "")
574                         (match_operand:BI 2 "const0_operand" "")])
575                       (label_ref (match_operand 3 "" ""))
576                       (pc)))]
577   ""
578   "")
580 ;; Conditional stores
582 (define_insn "setcc_from_bi"
583   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
584         (ne:SI (match_operand:BI 1 "nvptx_register_operand" "R")
585                (const_int 0)))]
586   ""
587   "%.\\tselp%t0 %0,-1,0,%1;")
589 (define_insn "sel_true<mode>"
590   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
591         (if_then_else:HSDIM
592           (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
593           (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
594           (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
595   ""
596   "%.\\tselp%t0\\t%0, %2, %3, %1;")
598 (define_insn "sel_true<mode>"
599   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
600         (if_then_else:SDFM
601           (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
602           (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
603           (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
604   ""
605   "%.\\tselp%t0\\t%0, %2, %3, %1;")
607 (define_insn "sel_false<mode>"
608   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
609         (if_then_else:HSDIM
610           (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
611           (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
612           (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
613   ""
614   "%.\\tselp%t0\\t%0, %3, %2, %1;")
616 (define_insn "sel_false<mode>"
617   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
618         (if_then_else:SDFM
619           (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
620           (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
621           (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
622   ""
623   "%.\\tselp%t0\\t%0, %3, %2, %1;")
625 (define_insn "setcc_int<mode>"
626   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
627         (match_operator:SI 1 "nvptx_comparison_operator"
628           [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
629            (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
630   ""
631   "%.\\tset%t0%c1\\t%0, %2, %3;")
633 (define_insn "setcc_int<mode>"
634   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
635         (match_operator:SI 1 "nvptx_float_comparison_operator"
636            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
637             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
638   ""
639   "%.\\tset%t0%c1\\t%0, %2, %3;")
641 (define_insn "setcc_float<mode>"
642   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
643         (match_operator:SF 1 "nvptx_comparison_operator"
644            [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
645             (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
646   ""
647   "%.\\tset%t0%c1\\t%0, %2, %3;")
649 (define_insn "setcc_float<mode>"
650   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
651         (match_operator:SF 1 "nvptx_float_comparison_operator"
652            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
653             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
654   ""
655   "%.\\tset%t0%c1\\t%0, %2, %3;")
657 (define_expand "cstorebi4"
658   [(set (match_operand:SI 0 "nvptx_register_operand")
659         (match_operator:SI 1 "ne_operator"
660          [(match_operand:BI 2 "nvptx_register_operand")
661           (match_operand:BI 3 "const0_operand")]))]
662   ""
663   "")
665 (define_expand "cstore<mode>4"
666   [(set (match_operand:SI 0 "nvptx_register_operand")
667         (match_operator:SI 1 "nvptx_comparison_operator"
668          [(match_operand:HSDIM 2 "nvptx_register_operand")
669           (match_operand:HSDIM 3 "nvptx_nonmemory_operand")]))]
670   ""
671   "")
673 (define_expand "cstore<mode>4"
674   [(set (match_operand:SI 0 "nvptx_register_operand")
675         (match_operator:SI 1 "nvptx_float_comparison_operator"
676          [(match_operand:SDFM 2 "nvptx_register_operand")
677           (match_operand:SDFM 3 "nvptx_nonmemory_operand")]))]
678   ""
679   "")
681 ;; Calls
683 (define_insn "call_insn"
684   [(match_parallel 2 "call_operation"
685     [(call (mem:QI (match_operand 0 "call_insn_operand" "Rs"))
686            (match_operand 1))])]
687   ""
689   return nvptx_output_call_insn (insn, NULL_RTX, operands[0]);
692 (define_insn "call_value_insn"
693   [(match_parallel 3 "call_operation"
694     [(set (match_operand 0 "nvptx_register_operand" "=R")
695           (call (mem:QI (match_operand 1 "call_insn_operand" "Rs"))
696                 (match_operand 2)))])]
697   ""
699   return nvptx_output_call_insn (insn, operands[0], operands[1]);
702 (define_expand "call"
703  [(match_operand 0 "" "")]
704  ""
706   nvptx_expand_call (NULL_RTX, operands[0]);
707   DONE;
710 (define_expand "call_value"
711   [(match_operand 0 "" "")
712    (match_operand 1 "" "")]
713  ""
715   nvptx_expand_call (operands[0], operands[1]);
716   DONE;
719 ;; Floating point arithmetic.
721 (define_insn "add<mode>3"
722   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
723         (plus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
724                    (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
725   ""
726   "%.\\tadd%t0\\t%0, %1, %2;")
728 (define_insn "sub<mode>3"
729   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
730         (minus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
731                     (match_operand:SDFM 2 "nvptx_register_operand" "R")))]
732   ""
733   "%.\\tsub%t0\\t%0, %1, %2;")
735 (define_insn "mul<mode>3"
736   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
737         (mult:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
738                    (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
739   ""
740   "%.\\tmul%t0\\t%0, %1, %2;")
742 (define_insn "fma<mode>4"
743   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
744         (fma:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
745                   (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
746                   (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
747   ""
748   "%.\\tfma%#%t0\\t%0, %1, %2, %3;")
750 (define_insn "div<mode>3"
751   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
752         (div:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
753                   (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
754   ""
755   "%.\\tdiv%#%t0\\t%0, %1, %2;")
757 (define_insn "copysign<mode>3"
758   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
759         (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")
760                       (match_operand:SDFM 2 "nvptx_register_operand" "R")]
761                       UNSPEC_COPYSIGN))]
762   ""
763   "%.\\tcopysign%t0\\t%0, %2, %1;")
765 (define_insn "smin<mode>3"
766   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
767         (smin:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
768                     (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
769   ""
770   "%.\\tmin%t0\\t%0, %1, %2;")
772 (define_insn "smax<mode>3"
773   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
774         (smax:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
775                     (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
776   ""
777   "%.\\tmax%t0\\t%0, %1, %2;")
779 (define_insn "abs<mode>2"
780   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
781         (abs:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
782   ""
783   "%.\\tabs%t0\\t%0, %1;")
785 (define_insn "neg<mode>2"
786   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
787         (neg:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
788   ""
789   "%.\\tneg%t0\\t%0, %1;")
791 (define_insn "sqrt<mode>2"
792   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
793         (sqrt:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
794   ""
795   "%.\\tsqrt%#%t0\\t%0, %1;")
797 (define_insn "sinsf2"
798   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
799         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
800                    UNSPEC_SIN))]
801   "flag_unsafe_math_optimizations"
802   "%.\\tsin.approx%t0\\t%0, %1;")
804 (define_insn "cossf2"
805   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
806         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
807                    UNSPEC_COS))]
808   "flag_unsafe_math_optimizations"
809   "%.\\tcos.approx%t0\\t%0, %1;")
811 (define_insn "log2sf2"
812   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
813         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
814                    UNSPEC_LOG2))]
815   "flag_unsafe_math_optimizations"
816   "%.\\tlg2.approx%t0\\t%0, %1;")
818 (define_insn "exp2sf2"
819   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
820         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
821                    UNSPEC_EXP2))]
822   "flag_unsafe_math_optimizations"
823   "%.\\tex2.approx%t0\\t%0, %1;")
825 ;; Conversions involving floating point
827 (define_insn "extendsfdf2"
828   [(set (match_operand:DF 0 "nvptx_register_operand" "=R")
829         (float_extend:DF (match_operand:SF 1 "nvptx_register_operand" "R")))]
830   ""
831   "%.\\tcvt%t0%t1\\t%0, %1;")
833 (define_insn "truncdfsf2"
834   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
835         (float_truncate:SF (match_operand:DF 1 "nvptx_register_operand" "R")))]
836   ""
837   "%.\\tcvt%#%t0%t1\\t%0, %1;")
839 (define_insn "floatunssi<mode>2"
840   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
841         (unsigned_float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
842   ""
843   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
845 (define_insn "floatsi<mode>2"
846   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
847         (float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
848   ""
849   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
851 (define_insn "floatunsdi<mode>2"
852   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
853         (unsigned_float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
854   ""
855   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
857 (define_insn "floatdi<mode>2"
858   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
859         (float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
860   ""
861   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
863 (define_insn "fixuns_trunc<mode>si2"
864   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
865         (unsigned_fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
866   ""
867   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
869 (define_insn "fix_trunc<mode>si2"
870   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
871         (fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
872   ""
873   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
875 (define_insn "fixuns_trunc<mode>di2"
876   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
877         (unsigned_fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
878   ""
879   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
881 (define_insn "fix_trunc<mode>di2"
882   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
883         (fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
884   ""
885   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
887 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
888                             UNSPEC_FPINT_CEIL UNSPEC_FPINT_NEARBYINT])
889 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
890                              (UNSPEC_FPINT_BTRUNC "btrunc")
891                              (UNSPEC_FPINT_CEIL "ceil")
892                              (UNSPEC_FPINT_NEARBYINT "nearbyint")])
893 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
894                                      (UNSPEC_FPINT_BTRUNC ".rzi")
895                                      (UNSPEC_FPINT_CEIL ".rpi")
896                                      (UNSPEC_FPINT_NEARBYINT "%#i")])
898 (define_insn "<FPINT:fpint_name><SDFM:mode>2"
899   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
900         (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
901                      FPINT))]
902   ""
903   "%.\\tcvt<FPINT:fpint_roundingmode>%t0%t1\\t%0, %1;")
905 (define_int_iterator FPINT2 [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_CEIL])
906 (define_int_attr fpint2_name [(UNSPEC_FPINT_FLOOR "lfloor")
907                              (UNSPEC_FPINT_CEIL "lceil")])
908 (define_int_attr fpint2_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
909                                      (UNSPEC_FPINT_CEIL ".rpi")])
911 (define_insn "<FPINT2:fpint2_name><SDFM:mode><SDIM:mode>2"
912   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
913         (unspec:SDIM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
914                      FPINT2))]
915   ""
916   "%.\\tcvt<FPINT2:fpint2_roundingmode>.s%T0%t1\\t%0, %1;")
918 ;; Miscellaneous
920 (define_insn "nop"
921   [(const_int 0)]
922   ""
923   "")
925 (define_insn "return"
926   [(return)]
927   ""
929   return nvptx_output_return ();
932 (define_expand "epilogue"
933   [(clobber (const_int 0))]
934   ""
936   emit_jump_insn (gen_return ());
937   DONE;
940 (define_expand "nonlocal_goto"
941   [(match_operand 0 "" "")
942    (match_operand 1 "" "")
943    (match_operand 2 "" "")
944    (match_operand 3 "" "")]
945   ""
947   sorry ("target cannot support nonlocal goto.");
948   emit_insn (gen_nop ());
949   DONE;
952 (define_expand "nonlocal_goto_receiver"
953   [(const_int 0)]
954   ""
956   sorry ("target cannot support nonlocal goto.");
959 (define_expand "allocate_stack"
960   [(match_operand 0 "nvptx_register_operand")
961    (match_operand 1 "nvptx_register_operand")]
962   ""
964   /* The ptx documentation specifies an alloca intrinsic (for 32 bit
965      only)  but notes it is not implemented.  The assembler emits a
966      confused error message.  Issue a blunt one now instead.  */
967   sorry ("target cannot support alloca.");
968   emit_insn (gen_nop ());
969   DONE;
970   if (TARGET_ABI64)
971     emit_insn (gen_allocate_stack_di (operands[0], operands[1]));
972   else
973     emit_insn (gen_allocate_stack_si (operands[0], operands[1]));
974   DONE;
977 (define_insn "allocate_stack_<mode>"
978   [(set (match_operand:P 0 "nvptx_register_operand" "=R")
979         (unspec:P [(match_operand:P 1 "nvptx_register_operand" "R")]
980                    UNSPEC_ALLOCA))]
981   ""
982   "%.\\tcall (%0), %%alloca, (%1);")
984 (define_expand "restore_stack_block"
985   [(match_operand 0 "register_operand" "")
986    (match_operand 1 "register_operand" "")]
987   ""
989   DONE;
992 (define_expand "restore_stack_function"
993   [(match_operand 0 "register_operand" "")
994    (match_operand 1 "register_operand" "")]
995   ""
997   DONE;
1000 (define_insn "trap"
1001   [(trap_if (const_int 1) (const_int 0))]
1002   ""
1003   "trap;")
1005 (define_insn "trap_if_true"
1006   [(trap_if (ne (match_operand:BI 0 "nvptx_register_operand" "R")
1007                 (const_int 0))
1008             (const_int 0))]
1009   ""
1010   "%j0 trap;")
1012 (define_insn "trap_if_false"
1013   [(trap_if (eq (match_operand:BI 0 "nvptx_register_operand" "R")
1014                 (const_int 0))
1015             (const_int 0))]
1016   ""
1017   "%J0 trap;")
1019 (define_expand "ctrap<mode>4"
1020   [(trap_if (match_operator 0 "nvptx_comparison_operator"
1021                             [(match_operand:SDIM 1 "nvptx_register_operand")
1022                              (match_operand:SDIM 2 "nvptx_nonmemory_operand")])
1023             (match_operand 3 "const0_operand"))]
1024   ""
1026   rtx t = nvptx_expand_compare (operands[0]);
1027   emit_insn (gen_trap_if_true (t));
1028   DONE;
1031 (define_insn "oacc_dim_size"
1032   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1033         (unspec:SI [(match_operand:SI 1 "const_int_operand" "")]
1034                    UNSPEC_DIM_SIZE))]
1035   ""
1037   static const char *const asms[] =
1038 { /* Must match oacc_loop_levels ordering.  */
1039   "%.\\tmov.u32\\t%0, %%nctaid.x;",     /* gang */
1040   "%.\\tmov.u32\\t%0, %%ntid.y;",       /* worker */
1041   "%.\\tmov.u32\\t%0, %%ntid.x;",       /* vector */
1043   return asms[INTVAL (operands[1])];
1046 (define_insn "oacc_dim_pos"
1047   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1048         (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "")]
1049                             UNSPECV_DIM_POS))]
1050   ""
1052   static const char *const asms[] =
1053 { /* Must match oacc_loop_levels ordering.  */
1054   "%.\\tmov.u32\\t%0, %%ctaid.x;",      /* gang */
1055   "%.\\tmov.u32\\t%0, %%tid.y;",        /* worker */
1056   "%.\\tmov.u32\\t%0, %%tid.x;",        /* vector */
1058   return asms[INTVAL (operands[1])];
1061 (define_insn "nvptx_fork"
1062   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1063                        UNSPECV_FORK)]
1064   ""
1065   "// fork %0;"
1068 (define_insn "nvptx_forked"
1069   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1070                        UNSPECV_FORKED)]
1071   ""
1072   "// forked %0;"
1075 (define_insn "nvptx_joining"
1076   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1077                        UNSPECV_JOINING)]
1078   ""
1079   "// joining %0;"
1082 (define_insn "nvptx_join"
1083   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1084                        UNSPECV_JOIN)]
1085   ""
1086   "// join %0;"
1089 (define_expand "oacc_fork"
1090   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1091         (match_operand:SI 1 "general_operand" ""))
1092    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1093                         UNSPECV_FORKED)]
1094   ""
1096   if (operands[0] != const0_rtx)
1097     emit_move_insn (operands[0], operands[1]);
1098   nvptx_expand_oacc_fork (INTVAL (operands[2]));
1099   DONE;
1102 (define_expand "oacc_join"
1103   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1104         (match_operand:SI 1 "general_operand" ""))
1105    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1106                         UNSPECV_JOIN)]
1107   ""
1109   if (operands[0] != const0_rtx)
1110     emit_move_insn (operands[0], operands[1]);
1111   nvptx_expand_oacc_join (INTVAL (operands[2]));
1112   DONE;
1115 ;; only 32-bit shuffles exist.
1116 (define_insn "nvptx_shuffle<mode>"
1117   [(set (match_operand:BITS 0 "nvptx_register_operand" "=R")
1118         (unspec:BITS
1119                 [(match_operand:BITS 1 "nvptx_register_operand" "R")
1120                  (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")
1121                  (match_operand:SI 3 "const_int_operand" "n")]
1122                   UNSPEC_SHUFFLE))]
1123   ""
1124   "%.\\tshfl%S3.b32\\t%0, %1, %2, 31;")
1126 ;; extract parts of a 64 bit object into 2 32-bit ints
1127 (define_insn "unpack<mode>si2"
1128   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1129         (unspec:SI [(match_operand:BITD 2 "nvptx_register_operand" "R")
1130                     (const_int 0)] UNSPEC_BIT_CONV))
1131    (set (match_operand:SI 1 "nvptx_register_operand" "=R")
1132         (unspec:SI [(match_dup 2) (const_int 1)] UNSPEC_BIT_CONV))]
1133   ""
1134   "%.\\tmov.b64\\t{%0,%1}, %2;")
1136 ;; pack 2 32-bit ints into a 64 bit object
1137 (define_insn "packsi<mode>2"
1138   [(set (match_operand:BITD 0 "nvptx_register_operand" "=R")
1139         (unspec:BITD [(match_operand:SI 1 "nvptx_register_operand" "R")
1140                       (match_operand:SI 2 "nvptx_register_operand" "R")]
1141                     UNSPEC_BIT_CONV))]
1142   ""
1143   "%.\\tmov.b64\\t%0, {%1,%2};")
1145 ;; Atomic insns.
1147 (define_expand "atomic_compare_and_swap<mode>"
1148   [(match_operand:SI 0 "nvptx_register_operand")        ;; bool success output
1149    (match_operand:SDIM 1 "nvptx_register_operand")      ;; oldval output
1150    (match_operand:SDIM 2 "memory_operand")              ;; memory
1151    (match_operand:SDIM 3 "nvptx_register_operand")      ;; expected input
1152    (match_operand:SDIM 4 "nvptx_register_operand")      ;; newval input
1153    (match_operand:SI 5 "const_int_operand")             ;; is_weak
1154    (match_operand:SI 6 "const_int_operand")             ;; success model
1155    (match_operand:SI 7 "const_int_operand")]            ;; failure model
1156   ""
1158   emit_insn (gen_atomic_compare_and_swap<mode>_1
1159     (operands[1], operands[2], operands[3], operands[4], operands[6]));
1161   rtx cond = gen_reg_rtx (BImode);
1162   emit_move_insn (cond, gen_rtx_EQ (BImode, operands[1], operands[3]));
1163   emit_insn (gen_sel_truesi (operands[0], cond, GEN_INT (1), GEN_INT (0)));
1164   DONE;
1167 (define_insn "atomic_compare_and_swap<mode>_1"
1168   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1169         (unspec_volatile:SDIM
1170           [(match_operand:SDIM 1 "memory_operand" "+m")
1171            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri")
1172            (match_operand:SDIM 3 "nvptx_nonmemory_operand" "Ri")
1173            (match_operand:SI 4 "const_int_operand")]
1174           UNSPECV_CAS))
1175    (set (match_dup 1)
1176         (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
1177   ""
1178   "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;")
1180 (define_insn "atomic_exchange<mode>"
1181   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")    ;; output
1182         (unspec_volatile:SDIM
1183           [(match_operand:SDIM 1 "memory_operand" "+m")         ;; memory
1184            (match_operand:SI 3 "const_int_operand")]            ;; model
1185           UNSPECV_XCHG))
1186    (set (match_dup 1)
1187         (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))] ;; input
1188   ""
1189   "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;")
1191 (define_insn "atomic_fetch_add<mode>"
1192   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1193         (unspec_volatile:SDIM
1194           [(plus:SDIM (match_dup 1)
1195                       (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1196            (match_operand:SI 3 "const_int_operand")]            ;; model
1197           UNSPECV_LOCK))
1198    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1199         (match_dup 1))]
1200   ""
1201   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1203 (define_insn "atomic_fetch_addsf"
1204   [(set (match_operand:SF 1 "memory_operand" "+m")
1205         (unspec_volatile:SF
1206          [(plus:SF (match_dup 1)
1207                    (match_operand:SF 2 "nvptx_nonmemory_operand" "RF"))
1208            (match_operand:SI 3 "const_int_operand")]            ;; model
1209           UNSPECV_LOCK))
1210    (set (match_operand:SF 0 "nvptx_register_operand" "=R")
1211         (match_dup 1))]
1212   ""
1213   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1215 (define_code_iterator any_logic [and ior xor])
1216 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1218 ;; Currently disabled until we add better subtarget support - requires sm_32.
1219 (define_insn "atomic_fetch_<logic><mode>"
1220   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1221         (unspec_volatile:SDIM
1222           [(any_logic:SDIM (match_dup 1)
1223                            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1224            (match_operand:SI 3 "const_int_operand")]            ;; model
1225           UNSPECV_LOCK))
1226    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1227         (match_dup 1))]
1228   "0"
1229   "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;")
1231 (define_insn "nvptx_barsync"
1232   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
1233                     UNSPECV_BARSYNC)]
1234   ""
1235   "\\tbar.sync\\t%0;")