2016-11-10 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / nvptx / nvptx.md
blobd117343c531d85d1ceee46cf4e3786e5fa2f5b0f
1 ;; Machine description for NVPTX.
2 ;; Copyright (C) 2014-2016 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_nonmemory_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_nonmemory_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_expand "sincossf3"
798   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
799         (unspec:SF [(match_operand:SF 2 "nvptx_register_operand" "R")]
800                    UNSPEC_COS))
801    (set (match_operand:SF 1 "nvptx_register_operand" "=R")
802         (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
803   "flag_unsafe_math_optimizations"
805   operands[2] = make_safe_from (operands[2], operands[0]);
808 (define_insn "sinsf2"
809   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
810         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
811                    UNSPEC_SIN))]
812   "flag_unsafe_math_optimizations"
813   "%.\\tsin.approx%t0\\t%0, %1;")
815 (define_insn "cossf2"
816   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
817         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
818                    UNSPEC_COS))]
819   "flag_unsafe_math_optimizations"
820   "%.\\tcos.approx%t0\\t%0, %1;")
822 (define_insn "log2sf2"
823   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
824         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
825                    UNSPEC_LOG2))]
826   "flag_unsafe_math_optimizations"
827   "%.\\tlg2.approx%t0\\t%0, %1;")
829 (define_insn "exp2sf2"
830   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
831         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
832                    UNSPEC_EXP2))]
833   "flag_unsafe_math_optimizations"
834   "%.\\tex2.approx%t0\\t%0, %1;")
836 ;; Conversions involving floating point
838 (define_insn "extendsfdf2"
839   [(set (match_operand:DF 0 "nvptx_register_operand" "=R")
840         (float_extend:DF (match_operand:SF 1 "nvptx_register_operand" "R")))]
841   ""
842   "%.\\tcvt%t0%t1\\t%0, %1;")
844 (define_insn "truncdfsf2"
845   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
846         (float_truncate:SF (match_operand:DF 1 "nvptx_register_operand" "R")))]
847   ""
848   "%.\\tcvt%#%t0%t1\\t%0, %1;")
850 (define_insn "floatunssi<mode>2"
851   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
852         (unsigned_float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
853   ""
854   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
856 (define_insn "floatsi<mode>2"
857   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
858         (float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
859   ""
860   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
862 (define_insn "floatunsdi<mode>2"
863   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
864         (unsigned_float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
865   ""
866   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
868 (define_insn "floatdi<mode>2"
869   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
870         (float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
871   ""
872   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
874 (define_insn "fixuns_trunc<mode>si2"
875   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
876         (unsigned_fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
877   ""
878   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
880 (define_insn "fix_trunc<mode>si2"
881   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
882         (fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
883   ""
884   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
886 (define_insn "fixuns_trunc<mode>di2"
887   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
888         (unsigned_fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
889   ""
890   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
892 (define_insn "fix_trunc<mode>di2"
893   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
894         (fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
895   ""
896   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
898 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
899                             UNSPEC_FPINT_CEIL UNSPEC_FPINT_NEARBYINT])
900 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
901                              (UNSPEC_FPINT_BTRUNC "btrunc")
902                              (UNSPEC_FPINT_CEIL "ceil")
903                              (UNSPEC_FPINT_NEARBYINT "nearbyint")])
904 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
905                                      (UNSPEC_FPINT_BTRUNC ".rzi")
906                                      (UNSPEC_FPINT_CEIL ".rpi")
907                                      (UNSPEC_FPINT_NEARBYINT "%#i")])
909 (define_insn "<FPINT:fpint_name><SDFM:mode>2"
910   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
911         (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
912                      FPINT))]
913   ""
914   "%.\\tcvt<FPINT:fpint_roundingmode>%t0%t1\\t%0, %1;")
916 (define_int_iterator FPINT2 [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_CEIL])
917 (define_int_attr fpint2_name [(UNSPEC_FPINT_FLOOR "lfloor")
918                              (UNSPEC_FPINT_CEIL "lceil")])
919 (define_int_attr fpint2_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
920                                      (UNSPEC_FPINT_CEIL ".rpi")])
922 (define_insn "<FPINT2:fpint2_name><SDFM:mode><SDIM:mode>2"
923   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
924         (unspec:SDIM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
925                      FPINT2))]
926   ""
927   "%.\\tcvt<FPINT2:fpint2_roundingmode>.s%T0%t1\\t%0, %1;")
929 ;; Miscellaneous
931 (define_insn "nop"
932   [(const_int 0)]
933   ""
934   "")
936 (define_insn "return"
937   [(return)]
938   ""
940   return nvptx_output_return ();
943 (define_expand "epilogue"
944   [(clobber (const_int 0))]
945   ""
947   emit_jump_insn (gen_return ());
948   DONE;
951 (define_expand "nonlocal_goto"
952   [(match_operand 0 "" "")
953    (match_operand 1 "" "")
954    (match_operand 2 "" "")
955    (match_operand 3 "" "")]
956   ""
958   sorry ("target cannot support nonlocal goto.");
959   emit_insn (gen_nop ());
960   DONE;
963 (define_expand "nonlocal_goto_receiver"
964   [(const_int 0)]
965   ""
967   sorry ("target cannot support nonlocal goto.");
970 (define_expand "allocate_stack"
971   [(match_operand 0 "nvptx_register_operand")
972    (match_operand 1 "nvptx_register_operand")]
973   ""
975   /* The ptx documentation specifies an alloca intrinsic (for 32 bit
976      only)  but notes it is not implemented.  The assembler emits a
977      confused error message.  Issue a blunt one now instead.  */
978   sorry ("target cannot support alloca.");
979   emit_insn (gen_nop ());
980   DONE;
981   if (TARGET_ABI64)
982     emit_insn (gen_allocate_stack_di (operands[0], operands[1]));
983   else
984     emit_insn (gen_allocate_stack_si (operands[0], operands[1]));
985   DONE;
988 (define_insn "allocate_stack_<mode>"
989   [(set (match_operand:P 0 "nvptx_register_operand" "=R")
990         (unspec:P [(match_operand:P 1 "nvptx_register_operand" "R")]
991                    UNSPEC_ALLOCA))]
992   ""
993   "%.\\tcall (%0), %%alloca, (%1);")
995 (define_expand "restore_stack_block"
996   [(match_operand 0 "register_operand" "")
997    (match_operand 1 "register_operand" "")]
998   ""
1000   DONE;
1003 (define_expand "restore_stack_function"
1004   [(match_operand 0 "register_operand" "")
1005    (match_operand 1 "register_operand" "")]
1006   ""
1008   DONE;
1011 (define_insn "trap"
1012   [(trap_if (const_int 1) (const_int 0))]
1013   ""
1014   "trap;")
1016 (define_insn "trap_if_true"
1017   [(trap_if (ne (match_operand:BI 0 "nvptx_register_operand" "R")
1018                 (const_int 0))
1019             (const_int 0))]
1020   ""
1021   "%j0 trap;")
1023 (define_insn "trap_if_false"
1024   [(trap_if (eq (match_operand:BI 0 "nvptx_register_operand" "R")
1025                 (const_int 0))
1026             (const_int 0))]
1027   ""
1028   "%J0 trap;")
1030 (define_expand "ctrap<mode>4"
1031   [(trap_if (match_operator 0 "nvptx_comparison_operator"
1032                             [(match_operand:SDIM 1 "nvptx_register_operand")
1033                              (match_operand:SDIM 2 "nvptx_nonmemory_operand")])
1034             (match_operand 3 "const0_operand"))]
1035   ""
1037   rtx t = nvptx_expand_compare (operands[0]);
1038   emit_insn (gen_trap_if_true (t));
1039   DONE;
1042 (define_insn "oacc_dim_size"
1043   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1044         (unspec:SI [(match_operand:SI 1 "const_int_operand" "")]
1045                    UNSPEC_DIM_SIZE))]
1046   ""
1048   static const char *const asms[] =
1049 { /* Must match oacc_loop_levels ordering.  */
1050   "%.\\tmov.u32\\t%0, %%nctaid.x;",     /* gang */
1051   "%.\\tmov.u32\\t%0, %%ntid.y;",       /* worker */
1052   "%.\\tmov.u32\\t%0, %%ntid.x;",       /* vector */
1054   return asms[INTVAL (operands[1])];
1057 (define_insn "oacc_dim_pos"
1058   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1059         (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "")]
1060                             UNSPECV_DIM_POS))]
1061   ""
1063   static const char *const asms[] =
1064 { /* Must match oacc_loop_levels ordering.  */
1065   "%.\\tmov.u32\\t%0, %%ctaid.x;",      /* gang */
1066   "%.\\tmov.u32\\t%0, %%tid.y;",        /* worker */
1067   "%.\\tmov.u32\\t%0, %%tid.x;",        /* vector */
1069   return asms[INTVAL (operands[1])];
1072 (define_insn "nvptx_fork"
1073   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1074                        UNSPECV_FORK)]
1075   ""
1076   "// fork %0;"
1079 (define_insn "nvptx_forked"
1080   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1081                        UNSPECV_FORKED)]
1082   ""
1083   "// forked %0;"
1086 (define_insn "nvptx_joining"
1087   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1088                        UNSPECV_JOINING)]
1089   ""
1090   "// joining %0;"
1093 (define_insn "nvptx_join"
1094   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1095                        UNSPECV_JOIN)]
1096   ""
1097   "// join %0;"
1100 (define_expand "oacc_fork"
1101   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1102         (match_operand:SI 1 "general_operand" ""))
1103    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1104                         UNSPECV_FORKED)]
1105   ""
1107   if (operands[0] != const0_rtx)
1108     emit_move_insn (operands[0], operands[1]);
1109   nvptx_expand_oacc_fork (INTVAL (operands[2]));
1110   DONE;
1113 (define_expand "oacc_join"
1114   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1115         (match_operand:SI 1 "general_operand" ""))
1116    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1117                         UNSPECV_JOIN)]
1118   ""
1120   if (operands[0] != const0_rtx)
1121     emit_move_insn (operands[0], operands[1]);
1122   nvptx_expand_oacc_join (INTVAL (operands[2]));
1123   DONE;
1126 ;; only 32-bit shuffles exist.
1127 (define_insn "nvptx_shuffle<mode>"
1128   [(set (match_operand:BITS 0 "nvptx_register_operand" "=R")
1129         (unspec:BITS
1130                 [(match_operand:BITS 1 "nvptx_register_operand" "R")
1131                  (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")
1132                  (match_operand:SI 3 "const_int_operand" "n")]
1133                   UNSPEC_SHUFFLE))]
1134   ""
1135   "%.\\tshfl%S3.b32\\t%0, %1, %2, 31;")
1137 ;; extract parts of a 64 bit object into 2 32-bit ints
1138 (define_insn "unpack<mode>si2"
1139   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1140         (unspec:SI [(match_operand:BITD 2 "nvptx_register_operand" "R")
1141                     (const_int 0)] UNSPEC_BIT_CONV))
1142    (set (match_operand:SI 1 "nvptx_register_operand" "=R")
1143         (unspec:SI [(match_dup 2) (const_int 1)] UNSPEC_BIT_CONV))]
1144   ""
1145   "%.\\tmov.b64\\t{%0,%1}, %2;")
1147 ;; pack 2 32-bit ints into a 64 bit object
1148 (define_insn "packsi<mode>2"
1149   [(set (match_operand:BITD 0 "nvptx_register_operand" "=R")
1150         (unspec:BITD [(match_operand:SI 1 "nvptx_register_operand" "R")
1151                       (match_operand:SI 2 "nvptx_register_operand" "R")]
1152                     UNSPEC_BIT_CONV))]
1153   ""
1154   "%.\\tmov.b64\\t%0, {%1,%2};")
1156 ;; Atomic insns.
1158 (define_expand "atomic_compare_and_swap<mode>"
1159   [(match_operand:SI 0 "nvptx_register_operand")        ;; bool success output
1160    (match_operand:SDIM 1 "nvptx_register_operand")      ;; oldval output
1161    (match_operand:SDIM 2 "memory_operand")              ;; memory
1162    (match_operand:SDIM 3 "nvptx_register_operand")      ;; expected input
1163    (match_operand:SDIM 4 "nvptx_register_operand")      ;; newval input
1164    (match_operand:SI 5 "const_int_operand")             ;; is_weak
1165    (match_operand:SI 6 "const_int_operand")             ;; success model
1166    (match_operand:SI 7 "const_int_operand")]            ;; failure model
1167   ""
1169   emit_insn (gen_atomic_compare_and_swap<mode>_1
1170     (operands[1], operands[2], operands[3], operands[4], operands[6]));
1172   rtx cond = gen_reg_rtx (BImode);
1173   emit_move_insn (cond, gen_rtx_EQ (BImode, operands[1], operands[3]));
1174   emit_insn (gen_sel_truesi (operands[0], cond, GEN_INT (1), GEN_INT (0)));
1175   DONE;
1178 (define_insn "atomic_compare_and_swap<mode>_1"
1179   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1180         (unspec_volatile:SDIM
1181           [(match_operand:SDIM 1 "memory_operand" "+m")
1182            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri")
1183            (match_operand:SDIM 3 "nvptx_nonmemory_operand" "Ri")
1184            (match_operand:SI 4 "const_int_operand")]
1185           UNSPECV_CAS))
1186    (set (match_dup 1)
1187         (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
1188   ""
1189   "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;")
1191 (define_insn "atomic_exchange<mode>"
1192   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")    ;; output
1193         (unspec_volatile:SDIM
1194           [(match_operand:SDIM 1 "memory_operand" "+m")         ;; memory
1195            (match_operand:SI 3 "const_int_operand")]            ;; model
1196           UNSPECV_XCHG))
1197    (set (match_dup 1)
1198         (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))] ;; input
1199   ""
1200   "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;")
1202 (define_insn "atomic_fetch_add<mode>"
1203   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1204         (unspec_volatile:SDIM
1205           [(plus:SDIM (match_dup 1)
1206                       (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1207            (match_operand:SI 3 "const_int_operand")]            ;; model
1208           UNSPECV_LOCK))
1209    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1210         (match_dup 1))]
1211   ""
1212   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1214 (define_insn "atomic_fetch_addsf"
1215   [(set (match_operand:SF 1 "memory_operand" "+m")
1216         (unspec_volatile:SF
1217          [(plus:SF (match_dup 1)
1218                    (match_operand:SF 2 "nvptx_nonmemory_operand" "RF"))
1219            (match_operand:SI 3 "const_int_operand")]            ;; model
1220           UNSPECV_LOCK))
1221    (set (match_operand:SF 0 "nvptx_register_operand" "=R")
1222         (match_dup 1))]
1223   ""
1224   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1226 (define_code_iterator any_logic [and ior xor])
1227 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1229 ;; Currently disabled until we add better subtarget support - requires sm_32.
1230 (define_insn "atomic_fetch_<logic><mode>"
1231   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1232         (unspec_volatile:SDIM
1233           [(any_logic:SDIM (match_dup 1)
1234                            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1235            (match_operand:SI 3 "const_int_operand")]            ;; model
1236           UNSPECV_LOCK))
1237    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1238         (match_dup 1))]
1239   "0"
1240   "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;")
1242 (define_insn "nvptx_barsync"
1243   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
1244                     UNSPECV_BARSYNC)]
1245   ""
1246   "\\tbar.sync\\t%0;")