* config/nvptx/nvptx-protos.h
[official-gcc.git] / gcc / config / nvptx / nvptx.md
blob182371c46ae1a18e0d7c71ea6292eb63adfa9e09
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_reg_or_mem_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 GET_CODE (op) != SYMBOL_REF || 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
122           || GET_CODE (XEXP (elt, 0)) != REG
123           || XEXP (elt, 0) == frame_pointer_rtx
124           || XEXP (elt, 0) == arg_pointer_rtx
125           || XEXP (elt, 0) == stack_pointer_rtx)
126         return false;
127     }
128   return true;
131 (define_constraint "P0"
132   "An integer with the value 0."
133   (and (match_code "const_int")
134        (match_test "ival == 0")))
136 (define_constraint "P1"
137   "An integer with the value 1."
138   (and (match_code "const_int")
139        (match_test "ival == 1")))
141 (define_constraint "Pn"
142   "An integer with the value -1."
143   (and (match_code "const_int")
144        (match_test "ival == -1")))
146 (define_constraint "R"
147   "A pseudo register."
148   (match_code "reg"))
150 (define_constraint "Ia"
151   "Any integer constant."
152   (and (match_code "const_int") (match_test "true")))
154 (define_mode_iterator QHSDISDFM [QI HI SI DI SF DF])
155 (define_mode_iterator QHSDIM [QI HI SI DI])
156 (define_mode_iterator HSDIM [HI SI DI])
157 (define_mode_iterator BHSDIM [BI HI SI DI])
158 (define_mode_iterator SDIM [SI DI])
159 (define_mode_iterator SDISDFM [SI DI SF DF])
160 (define_mode_iterator QHIM [QI HI])
161 (define_mode_iterator QHSIM [QI HI SI])
162 (define_mode_iterator SDFM [SF DF])
163 (define_mode_iterator SDCM [SC DC])
164 (define_mode_iterator BITS [SI SF])
165 (define_mode_iterator BITD [DI DF])
167 ;; This mode iterator allows :P to be used for patterns that operate on
168 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
169 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
171 ;; We should get away with not defining memory alternatives, since we don't
172 ;; get variables in this mode and pseudos are never spilled.
173 (define_insn "movbi"
174   [(set (match_operand:BI 0 "nvptx_register_operand" "=R,R,R")
175         (match_operand:BI 1 "nvptx_nonmemory_operand" "R,P0,Pn"))]
176   ""
177   "@
178    %.\\tmov%t0\\t%0, %1;
179    %.\\tsetp.eq.u32\\t%0, 1, 0;
180    %.\\tsetp.eq.u32\\t%0, 1, 1;")
182 (define_insn "*mov<mode>_insn"
183   [(set (match_operand:QHSDIM 0 "nonimmediate_operand" "=R,R,m")
184         (match_operand:QHSDIM 1 "general_operand" "Ri,m,R"))]
185   "!MEM_P (operands[0]) || REG_P (operands[1])"
187   if (which_alternative == 1)
188     return "%.\\tld%A1%u1\\t%0, %1;";
189   if (which_alternative == 2)
190     return "%.\\tst%A0%u0\\t%0, %1;";
192   return nvptx_output_mov_insn (operands[0], operands[1]);
194   [(set_attr "subregs_ok" "true")])
196 (define_insn "*mov<mode>_insn"
197   [(set (match_operand:SDFM 0 "nonimmediate_operand" "=R,R,m")
198         (match_operand:SDFM 1 "general_operand" "RF,m,R"))]
199   "!MEM_P (operands[0]) || REG_P (operands[1])"
201   if (which_alternative == 1)
202     return "%.\\tld%A1%u0\\t%0, %1;";
203   if (which_alternative == 2)
204     return "%.\\tst%A0%u1\\t%0, %1;";
206   return nvptx_output_mov_insn (operands[0], operands[1]);
208   [(set_attr "subregs_ok" "true")])
210 (define_insn "load_arg_reg<mode>"
211   [(set (match_operand:QHIM 0 "nvptx_register_operand" "=R")
212         (unspec:QHIM [(match_operand 1 "const_int_operand" "n")]
213                      UNSPEC_ARG_REG))]
214   ""
215   "%.\\tcvt%t0.u32\\t%0, %%ar%1;")
217 (define_insn "load_arg_reg<mode>"
218   [(set (match_operand:SDISDFM 0 "nvptx_register_operand" "=R")
219         (unspec:SDISDFM [(match_operand 1 "const_int_operand" "n")]
220                         UNSPEC_ARG_REG))]
221   ""
222   "%.\\tmov%t0\\t%0, %%ar%1;")
224 (define_expand "mov<mode>"
225   [(set (match_operand:QHSDISDFM 0 "nonimmediate_operand" "")
226         (match_operand:QHSDISDFM 1 "general_operand" ""))]
227   ""
229   if (MEM_P (operands[0]) && !REG_P (operands[1]))
230     {
231       rtx tmp = gen_reg_rtx (<MODE>mode);
232       emit_move_insn (tmp, operands[1]);
233       emit_move_insn (operands[0], tmp);
234       DONE;
235     }
238 (define_insn "zero_extendqihi2"
239   [(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
240         (zero_extend:HI (match_operand:QI 1 "nvptx_reg_or_mem_operand" "R,m")))]
241   ""
242   "@
243    %.\\tcvt.u16.u%T1\\t%0, %1;
244    %.\\tld%A1.u8\\t%0, %1;"
245   [(set_attr "subregs_ok" "true")])
247 (define_insn "zero_extend<mode>si2"
248   [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
249         (zero_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
250   ""
251   "@
252    %.\\tcvt.u32.u%T1\\t%0, %1;
253    %.\\tld%A1.u%T1\\t%0, %1;"
254   [(set_attr "subregs_ok" "true")])
256 (define_insn "zero_extend<mode>di2"
257   [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
258         (zero_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
259   ""
260   "@
261    %.\\tcvt.u64.u%T1\\t%0, %1;
262    %.\\tld%A1%u1\\t%0, %1;"
263   [(set_attr "subregs_ok" "true")])
265 (define_insn "extend<mode>si2"
266   [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
267         (sign_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
268   ""
269   "@
270    %.\\tcvt.s32.s%T1\\t%0, %1;
271    %.\\tld%A1.s%T1\\t%0, %1;"
272   [(set_attr "subregs_ok" "true")])
274 (define_insn "extend<mode>di2"
275   [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
276         (sign_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
277   ""
278   "@
279    %.\\tcvt.s64.s%T1\\t%0, %1;
280    %.\\tld%A1.s%T1\\t%0, %1;"
281   [(set_attr "subregs_ok" "true")])
283 (define_insn "trunchiqi2"
284   [(set (match_operand:QI 0 "nvptx_reg_or_mem_operand" "=R,m")
285         (truncate:QI (match_operand:HI 1 "nvptx_register_operand" "R,R")))]
286   ""
287   "@
288    %.\\tcvt%t0.u16\\t%0, %1;
289    %.\\tst%A0.u8\\t%0, %1;"
290   [(set_attr "subregs_ok" "true")])
292 (define_insn "truncsi<mode>2"
293   [(set (match_operand:QHIM 0 "nvptx_reg_or_mem_operand" "=R,m")
294         (truncate:QHIM (match_operand:SI 1 "nvptx_register_operand" "R,R")))]
295   ""
296   "@
297    %.\\tcvt%t0.u32\\t%0, %1;
298    %.\\tst%A0.u%T0\\t%0, %1;"
299   [(set_attr "subregs_ok" "true")])
301 (define_insn "truncdi<mode>2"
302   [(set (match_operand:QHSIM 0 "nvptx_reg_or_mem_operand" "=R,m")
303         (truncate:QHSIM (match_operand:DI 1 "nvptx_register_operand" "R,R")))]
304   ""
305   "@
306    %.\\tcvt%t0.u64\\t%0, %1;
307    %.\\tst%A0.u%T0\\t%0, %1;"
308   [(set_attr "subregs_ok" "true")])
310 ;; Integer arithmetic
312 (define_insn "add<mode>3"
313   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
314         (plus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
315                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
316   ""
317   "%.\\tadd%t0\\t%0, %1, %2;")
319 (define_insn "sub<mode>3"
320   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
321         (minus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
322                      (match_operand:HSDIM 2 "nvptx_register_operand" "R")))]
323   ""
324   "%.\\tsub%t0\\t%0, %1, %2;")
326 (define_insn "mul<mode>3"
327   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
328         (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
329                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
330   ""
331   "%.\\tmul.lo%t0\\t%0, %1, %2;")
333 (define_insn "*mad<mode>3"
334   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
335         (plus:HSDIM (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
336                                 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri"))
337                     (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
338   ""
339   "%.\\tmad.lo%t0\\t%0, %1, %2, %3;")
341 (define_insn "div<mode>3"
342   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
343         (div:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
344                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
345   ""
346   "%.\\tdiv.s%T0\\t%0, %1, %2;")
348 (define_insn "udiv<mode>3"
349   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
350         (udiv:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
351                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
352   ""
353   "%.\\tdiv.u%T0\\t%0, %1, %2;")
355 (define_insn "mod<mode>3"
356   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
357         (mod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
358                    (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
359   ""
360   "%.\\trem.s%T0\\t%0, %1, %2;")
362 (define_insn "umod<mode>3"
363   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
364         (umod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
365                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
366   ""
367   "%.\\trem.u%T0\\t%0, %1, %2;")
369 (define_insn "smin<mode>3"
370   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
371         (smin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
372                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
373   ""
374   "%.\\tmin.s%T0\\t%0, %1, %2;")
376 (define_insn "umin<mode>3"
377   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
378         (umin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
379                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
380   ""
381   "%.\\tmin.u%T0\\t%0, %1, %2;")
383 (define_insn "smax<mode>3"
384   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
385         (smax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
386                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
387   ""
388   "%.\\tmax.s%T0\\t%0, %1, %2;")
390 (define_insn "umax<mode>3"
391   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
392         (umax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
393                     (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
394   ""
395   "%.\\tmax.u%T0\\t%0, %1, %2;")
397 (define_insn "abs<mode>2"
398   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
399         (abs:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
400   ""
401   "%.\\tabs.s%T0\\t%0, %1;")
403 (define_insn "neg<mode>2"
404   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
405         (neg:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
406   ""
407   "%.\\tneg.s%T0\\t%0, %1;")
409 (define_insn "one_cmpl<mode>2"
410   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
411         (not:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
412   ""
413   "%.\\tnot.b%T0\\t%0, %1;")
415 (define_insn "bitrev<mode>2"
416   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
417         (unspec:SDIM [(match_operand:SDIM 1 "nvptx_register_operand" "R")]
418                      UNSPEC_BITREV))]
419   ""
420   "%.\\tbrev.b%T0\\t%0, %1;")
422 (define_insn "clz<mode>2"
423   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
424         (clz:SI (match_operand:SDIM 1 "nvptx_register_operand" "R")))]
425   ""
426   "%.\\tclz.b%T1\\t%0, %1;")
428 (define_expand "ctz<mode>2"
429   [(set (match_operand:SI 0 "nvptx_register_operand" "")
430         (ctz:SI (match_operand:SDIM 1 "nvptx_register_operand" "")))]
431   ""
433   rtx tmpreg = gen_reg_rtx (<MODE>mode);
434   emit_insn (gen_bitrev<mode>2 (tmpreg, operands[1]));
435   emit_insn (gen_clz<mode>2 (operands[0], tmpreg));
436   DONE;
439 ;; Shifts
441 (define_insn "ashl<mode>3"
442   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
443         (ashift:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
444                      (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
445   ""
446   "%.\\tshl.b%T0\\t%0, %1, %2;")
448 (define_insn "ashr<mode>3"
449   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
450         (ashiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
451                        (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
452   ""
453   "%.\\tshr.s%T0\\t%0, %1, %2;")
455 (define_insn "lshr<mode>3"
456   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
457         (lshiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
458                        (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
459   ""
460   "%.\\tshr.u%T0\\t%0, %1, %2;")
462 ;; Logical operations
464 (define_insn "and<mode>3"
465   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
466         (and:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
467                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
468   ""
469   "%.\\tand.b%T0\\t%0, %1, %2;")
471 (define_insn "ior<mode>3"
472   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
473         (ior:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
474                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
475   ""
476   "%.\\tor.b%T0\\t%0, %1, %2;")
478 (define_insn "xor<mode>3"
479   [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
480         (xor:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
481                     (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
482   ""
483   "%.\\txor.b%T0\\t%0, %1, %2;")
485 ;; Comparisons and branches
487 (define_insn "*cmp<mode>"
488   [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
489         (match_operator:BI 1 "nvptx_comparison_operator"
490            [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
491             (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
492   ""
493   "%.\\tsetp%c1\\t%0, %2, %3;")
495 (define_insn "*cmp<mode>"
496   [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
497         (match_operator:BI 1 "nvptx_float_comparison_operator"
498            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
499             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
500   ""
501   "%.\\tsetp%c1\\t%0, %2, %3;")
503 (define_insn "jump"
504   [(set (pc)
505         (label_ref (match_operand 0 "" "")))]
506   ""
507   "%.\\tbra\\t%l0;")
509 (define_insn "br_true"
510   [(set (pc)
511         (if_then_else (ne (match_operand:BI 0 "nvptx_register_operand" "R")
512                           (const_int 0))
513                       (label_ref (match_operand 1 "" ""))
514                       (pc)))]
515   ""
516   "%j0\\tbra\\t%l1;")
518 (define_insn "br_false"
519   [(set (pc)
520         (if_then_else (eq (match_operand:BI 0 "nvptx_register_operand" "R")
521                           (const_int 0))
522                       (label_ref (match_operand 1 "" ""))
523                       (pc)))]
524   ""
525   "%J0\\tbra\\t%l1;")
527 ;; unified conditional branch
528 (define_insn "br_true_uni"
529   [(set (pc) (if_then_else
530         (ne (unspec:BI [(match_operand:BI 0 "nvptx_register_operand" "R")]
531                        UNSPEC_BR_UNIFIED) (const_int 0))
532         (label_ref (match_operand 1 "" "")) (pc)))]
533   ""
534   "%j0\\tbra.uni\\t%l1;")
536 (define_insn "br_false_uni"
537   [(set (pc) (if_then_else
538         (eq (unspec:BI [(match_operand:BI 0 "nvptx_register_operand" "R")]
539                        UNSPEC_BR_UNIFIED) (const_int 0))
540         (label_ref (match_operand 1 "" "")) (pc)))]
541   ""
542   "%J0\\tbra.uni\\t%l1;")
544 (define_expand "cbranch<mode>4"
545   [(set (pc)
546         (if_then_else (match_operator 0 "nvptx_comparison_operator"
547                        [(match_operand:HSDIM 1 "nvptx_register_operand" "")
548                         (match_operand:HSDIM 2 "nvptx_register_operand" "")])
549                       (label_ref (match_operand 3 "" ""))
550                       (pc)))]
551   ""
553   rtx t = nvptx_expand_compare (operands[0]);
554   operands[0] = t;
555   operands[1] = XEXP (t, 0);
556   operands[2] = XEXP (t, 1);
559 (define_expand "cbranch<mode>4"
560   [(set (pc)
561         (if_then_else (match_operator 0 "nvptx_float_comparison_operator"
562                        [(match_operand:SDFM 1 "nvptx_register_operand" "")
563                         (match_operand:SDFM 2 "nvptx_register_operand" "")])
564                       (label_ref (match_operand 3 "" ""))
565                       (pc)))]
566   ""
568   rtx t = nvptx_expand_compare (operands[0]);
569   operands[0] = t;
570   operands[1] = XEXP (t, 0);
571   operands[2] = XEXP (t, 1);
574 (define_expand "cbranchbi4"
575   [(set (pc)
576         (if_then_else (match_operator 0 "predicate_operator"
577                        [(match_operand:BI 1 "nvptx_register_operand" "")
578                         (match_operand:BI 2 "const0_operand" "")])
579                       (label_ref (match_operand 3 "" ""))
580                       (pc)))]
581   ""
582   "")
584 ;; Conditional stores
586 (define_insn "setcc_from_bi"
587   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
588         (ne:SI (match_operand:BI 1 "nvptx_register_operand" "R")
589                (const_int 0)))]
590   ""
591   "%.\\tselp%t0 %0,-1,0,%1;")
593 (define_insn "sel_true<mode>"
594   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
595         (if_then_else:HSDIM
596           (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
597           (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
598           (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
599   ""
600   "%.\\tselp%t0\\t%0, %2, %3, %1;")
602 (define_insn "sel_true<mode>"
603   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
604         (if_then_else:SDFM
605           (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
606           (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
607           (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
608   ""
609   "%.\\tselp%t0\\t%0, %2, %3, %1;")
611 (define_insn "sel_false<mode>"
612   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
613         (if_then_else:HSDIM
614           (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
615           (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
616           (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
617   ""
618   "%.\\tselp%t0\\t%0, %3, %2, %1;")
620 (define_insn "sel_false<mode>"
621   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
622         (if_then_else:SDFM
623           (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
624           (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
625           (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
626   ""
627   "%.\\tselp%t0\\t%0, %3, %2, %1;")
629 (define_insn "setcc_int<mode>"
630   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
631         (match_operator:SI 1 "nvptx_comparison_operator"
632           [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
633            (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
634   ""
635   "%.\\tset%t0%c1\\t%0, %2, %3;")
637 (define_insn "setcc_int<mode>"
638   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
639         (match_operator:SI 1 "nvptx_float_comparison_operator"
640            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
641             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
642   ""
643   "%.\\tset%t0%c1\\t%0, %2, %3;")
645 (define_insn "setcc_float<mode>"
646   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
647         (match_operator:SF 1 "nvptx_comparison_operator"
648            [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
649             (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
650   ""
651   "%.\\tset%t0%c1\\t%0, %2, %3;")
653 (define_insn "setcc_float<mode>"
654   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
655         (match_operator:SF 1 "nvptx_float_comparison_operator"
656            [(match_operand:SDFM 2 "nvptx_register_operand" "R")
657             (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
658   ""
659   "%.\\tset%t0%c1\\t%0, %2, %3;")
661 (define_expand "cstorebi4"
662   [(set (match_operand:SI 0 "nvptx_register_operand")
663         (match_operator:SI 1 "ne_operator"
664          [(match_operand:BI 2 "nvptx_register_operand")
665           (match_operand:BI 3 "const0_operand")]))]
666   ""
667   "")
669 (define_expand "cstore<mode>4"
670   [(set (match_operand:SI 0 "nvptx_register_operand")
671         (match_operator:SI 1 "nvptx_comparison_operator"
672          [(match_operand:HSDIM 2 "nvptx_register_operand")
673           (match_operand:HSDIM 3 "nvptx_nonmemory_operand")]))]
674   ""
675   "")
677 (define_expand "cstore<mode>4"
678   [(set (match_operand:SI 0 "nvptx_register_operand")
679         (match_operator:SI 1 "nvptx_float_comparison_operator"
680          [(match_operand:SDFM 2 "nvptx_register_operand")
681           (match_operand:SDFM 3 "nvptx_nonmemory_operand")]))]
682   ""
683   "")
685 ;; Calls
687 (define_insn "call_insn"
688   [(match_parallel 2 "call_operation"
689     [(call (mem:QI (match_operand 0 "call_insn_operand" "Rs"))
690            (match_operand 1))])]
691   ""
693   return nvptx_output_call_insn (insn, NULL_RTX, operands[0]);
696 (define_insn "call_value_insn"
697   [(match_parallel 3 "call_operation"
698     [(set (match_operand 0 "nvptx_register_operand" "=R")
699           (call (mem:QI (match_operand 1 "call_insn_operand" "Rs"))
700                 (match_operand 2)))])]
701   ""
703   return nvptx_output_call_insn (insn, operands[0], operands[1]);
706 (define_expand "call"
707  [(match_operand 0 "" "")]
708  ""
710   nvptx_expand_call (NULL_RTX, operands[0]);
711   DONE;
714 (define_expand "call_value"
715   [(match_operand 0 "" "")
716    (match_operand 1 "" "")]
717  ""
719   nvptx_expand_call (operands[0], operands[1]);
720   DONE;
723 ;; Floating point arithmetic.
725 (define_insn "add<mode>3"
726   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
727         (plus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
728                    (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
729   ""
730   "%.\\tadd%t0\\t%0, %1, %2;")
732 (define_insn "sub<mode>3"
733   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
734         (minus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
735                     (match_operand:SDFM 2 "nvptx_register_operand" "R")))]
736   ""
737   "%.\\tsub%t0\\t%0, %1, %2;")
739 (define_insn "mul<mode>3"
740   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
741         (mult:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
742                    (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
743   ""
744   "%.\\tmul%t0\\t%0, %1, %2;")
746 (define_insn "fma<mode>4"
747   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
748         (fma:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
749                   (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
750                   (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
751   ""
752   "%.\\tfma%#%t0\\t%0, %1, %2, %3;")
754 (define_insn "div<mode>3"
755   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
756         (div:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
757                   (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
758   ""
759   "%.\\tdiv%#%t0\\t%0, %1, %2;")
761 (define_insn "copysign<mode>3"
762   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
763         (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")
764                       (match_operand:SDFM 2 "nvptx_register_operand" "R")]
765                       UNSPEC_COPYSIGN))]
766   ""
767   "%.\\tcopysign%t0\\t%0, %2, %1;")
769 (define_insn "smin<mode>3"
770   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
771         (smin:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
772                     (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
773   ""
774   "%.\\tmin%t0\\t%0, %1, %2;")
776 (define_insn "smax<mode>3"
777   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
778         (smax:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
779                     (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
780   ""
781   "%.\\tmax%t0\\t%0, %1, %2;")
783 (define_insn "abs<mode>2"
784   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
785         (abs:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
786   ""
787   "%.\\tabs%t0\\t%0, %1;")
789 (define_insn "neg<mode>2"
790   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
791         (neg:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
792   ""
793   "%.\\tneg%t0\\t%0, %1;")
795 (define_insn "sqrt<mode>2"
796   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
797         (sqrt:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
798   ""
799   "%.\\tsqrt%#%t0\\t%0, %1;")
801 (define_insn "sinsf2"
802   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
803         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
804                    UNSPEC_SIN))]
805   "flag_unsafe_math_optimizations"
806   "%.\\tsin.approx%t0\\t%0, %1;")
808 (define_insn "cossf2"
809   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
810         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
811                    UNSPEC_COS))]
812   "flag_unsafe_math_optimizations"
813   "%.\\tcos.approx%t0\\t%0, %1;")
815 (define_insn "log2sf2"
816   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
817         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
818                    UNSPEC_LOG2))]
819   "flag_unsafe_math_optimizations"
820   "%.\\tlg2.approx%t0\\t%0, %1;")
822 (define_insn "exp2sf2"
823   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
824         (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
825                    UNSPEC_EXP2))]
826   "flag_unsafe_math_optimizations"
827   "%.\\tex2.approx%t0\\t%0, %1;")
829 ;; Conversions involving floating point
831 (define_insn "extendsfdf2"
832   [(set (match_operand:DF 0 "nvptx_register_operand" "=R")
833         (float_extend:DF (match_operand:SF 1 "nvptx_register_operand" "R")))]
834   ""
835   "%.\\tcvt%t0%t1\\t%0, %1;")
837 (define_insn "truncdfsf2"
838   [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
839         (float_truncate:SF (match_operand:DF 1 "nvptx_register_operand" "R")))]
840   ""
841   "%.\\tcvt%#%t0%t1\\t%0, %1;")
843 (define_insn "floatunssi<mode>2"
844   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
845         (unsigned_float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
846   ""
847   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
849 (define_insn "floatsi<mode>2"
850   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
851         (float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
852   ""
853   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
855 (define_insn "floatunsdi<mode>2"
856   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
857         (unsigned_float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
858   ""
859   "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
861 (define_insn "floatdi<mode>2"
862   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
863         (float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
864   ""
865   "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
867 (define_insn "fixuns_trunc<mode>si2"
868   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
869         (unsigned_fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
870   ""
871   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
873 (define_insn "fix_trunc<mode>si2"
874   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
875         (fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
876   ""
877   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
879 (define_insn "fixuns_trunc<mode>di2"
880   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
881         (unsigned_fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
882   ""
883   "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
885 (define_insn "fix_trunc<mode>di2"
886   [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
887         (fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
888   ""
889   "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
891 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
892                             UNSPEC_FPINT_CEIL UNSPEC_FPINT_NEARBYINT])
893 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
894                              (UNSPEC_FPINT_BTRUNC "btrunc")
895                              (UNSPEC_FPINT_CEIL "ceil")
896                              (UNSPEC_FPINT_NEARBYINT "nearbyint")])
897 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
898                                      (UNSPEC_FPINT_BTRUNC ".rzi")
899                                      (UNSPEC_FPINT_CEIL ".rpi")
900                                      (UNSPEC_FPINT_NEARBYINT "%#i")])
902 (define_insn "<FPINT:fpint_name><SDFM:mode>2"
903   [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
904         (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
905                      FPINT))]
906   ""
907   "%.\\tcvt<FPINT:fpint_roundingmode>%t0%t1\\t%0, %1;")
909 (define_int_iterator FPINT2 [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_CEIL])
910 (define_int_attr fpint2_name [(UNSPEC_FPINT_FLOOR "lfloor")
911                              (UNSPEC_FPINT_CEIL "lceil")])
912 (define_int_attr fpint2_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
913                                      (UNSPEC_FPINT_CEIL ".rpi")])
915 (define_insn "<FPINT2:fpint2_name><SDFM:mode><SDIM:mode>2"
916   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
917         (unspec:SDIM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
918                      FPINT2))]
919   ""
920   "%.\\tcvt<FPINT2:fpint2_roundingmode>.s%T0%t1\\t%0, %1;")
922 ;; Miscellaneous
924 (define_insn "nop"
925   [(const_int 0)]
926   ""
927   "")
929 (define_insn "return"
930   [(return)]
931   ""
933   return nvptx_output_return ();
936 (define_expand "epilogue"
937   [(clobber (const_int 0))]
938   ""
940   emit_jump_insn (gen_return ());
941   DONE;
944 (define_expand "nonlocal_goto"
945   [(match_operand 0 "" "")
946    (match_operand 1 "" "")
947    (match_operand 2 "" "")
948    (match_operand 3 "" "")]
949   ""
951   sorry ("target cannot support nonlocal goto.");
952   emit_insn (gen_nop ());
953   DONE;
956 (define_expand "nonlocal_goto_receiver"
957   [(const_int 0)]
958   ""
960   sorry ("target cannot support nonlocal goto.");
963 (define_expand "allocate_stack"
964   [(match_operand 0 "nvptx_register_operand")
965    (match_operand 1 "nvptx_register_operand")]
966   ""
968   /* The ptx documentation specifies an alloca intrinsic (for 32 bit
969      only)  but notes it is not implemented.  The assembler emits a
970      confused error message.  Issue a blunt one now instead.  */
971   sorry ("target cannot support alloca.");
972   emit_insn (gen_nop ());
973   DONE;
974   if (TARGET_ABI64)
975     emit_insn (gen_allocate_stack_di (operands[0], operands[1]));
976   else
977     emit_insn (gen_allocate_stack_si (operands[0], operands[1]));
978   DONE;
981 (define_insn "allocate_stack_<mode>"
982   [(set (match_operand:P 0 "nvptx_register_operand" "=R")
983         (unspec:P [(match_operand:P 1 "nvptx_register_operand" "R")]
984                    UNSPEC_ALLOCA))]
985   ""
986   "%.\\tcall (%0), %%alloca, (%1);")
988 (define_expand "restore_stack_block"
989   [(match_operand 0 "register_operand" "")
990    (match_operand 1 "register_operand" "")]
991   ""
993   DONE;
996 (define_expand "restore_stack_function"
997   [(match_operand 0 "register_operand" "")
998    (match_operand 1 "register_operand" "")]
999   ""
1001   DONE;
1004 (define_insn "trap"
1005   [(trap_if (const_int 1) (const_int 0))]
1006   ""
1007   "trap;")
1009 (define_insn "trap_if_true"
1010   [(trap_if (ne (match_operand:BI 0 "nvptx_register_operand" "R")
1011                 (const_int 0))
1012             (const_int 0))]
1013   ""
1014   "%j0 trap;")
1016 (define_insn "trap_if_false"
1017   [(trap_if (eq (match_operand:BI 0 "nvptx_register_operand" "R")
1018                 (const_int 0))
1019             (const_int 0))]
1020   ""
1021   "%J0 trap;")
1023 (define_expand "ctrap<mode>4"
1024   [(trap_if (match_operator 0 "nvptx_comparison_operator"
1025                             [(match_operand:SDIM 1 "nvptx_register_operand")
1026                              (match_operand:SDIM 2 "nvptx_nonmemory_operand")])
1027             (match_operand 3 "const0_operand"))]
1028   ""
1030   rtx t = nvptx_expand_compare (operands[0]);
1031   emit_insn (gen_trap_if_true (t));
1032   DONE;
1035 (define_insn "oacc_dim_size"
1036   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1037         (unspec:SI [(match_operand:SI 1 "const_int_operand" "")]
1038                    UNSPEC_DIM_SIZE))]
1039   ""
1041   static const char *const asms[] =
1042 { /* Must match oacc_loop_levels ordering.  */
1043   "%.\\tmov.u32\\t%0, %%nctaid.x;",     /* gang */
1044   "%.\\tmov.u32\\t%0, %%ntid.y;",       /* worker */
1045   "%.\\tmov.u32\\t%0, %%ntid.x;",       /* vector */
1047   return asms[INTVAL (operands[1])];
1050 (define_insn "oacc_dim_pos"
1051   [(set (match_operand:SI 0 "nvptx_register_operand" "")
1052         (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "")]
1053                             UNSPECV_DIM_POS))]
1054   ""
1056   static const char *const asms[] =
1057 { /* Must match oacc_loop_levels ordering.  */
1058   "%.\\tmov.u32\\t%0, %%ctaid.x;",      /* gang */
1059   "%.\\tmov.u32\\t%0, %%tid.y;",        /* worker */
1060   "%.\\tmov.u32\\t%0, %%tid.x;",        /* vector */
1062   return asms[INTVAL (operands[1])];
1065 (define_insn "nvptx_fork"
1066   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1067                        UNSPECV_FORK)]
1068   ""
1069   "// fork %0;"
1072 (define_insn "nvptx_forked"
1073   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1074                        UNSPECV_FORKED)]
1075   ""
1076   "// forked %0;"
1079 (define_insn "nvptx_joining"
1080   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1081                        UNSPECV_JOINING)]
1082   ""
1083   "// joining %0;"
1086 (define_insn "nvptx_join"
1087   [(unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "")]
1088                        UNSPECV_JOIN)]
1089   ""
1090   "// join %0;"
1093 (define_expand "oacc_fork"
1094   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1095         (match_operand:SI 1 "general_operand" ""))
1096    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1097                         UNSPECV_FORKED)]
1098   ""
1100   if (operands[0] != const0_rtx)
1101     emit_move_insn (operands[0], operands[1]);
1102   nvptx_expand_oacc_fork (INTVAL (operands[2]));
1103   DONE;
1106 (define_expand "oacc_join"
1107   [(set (match_operand:SI 0 "nvptx_nonmemory_operand" "")
1108         (match_operand:SI 1 "general_operand" ""))
1109    (unspec_volatile:SI [(match_operand:SI 2 "const_int_operand" "")]
1110                         UNSPECV_JOIN)]
1111   ""
1113   if (operands[0] != const0_rtx)
1114     emit_move_insn (operands[0], operands[1]);
1115   nvptx_expand_oacc_join (INTVAL (operands[2]));
1116   DONE;
1119 ;; only 32-bit shuffles exist.
1120 (define_insn "nvptx_shuffle<mode>"
1121   [(set (match_operand:BITS 0 "nvptx_register_operand" "=R")
1122         (unspec:BITS
1123                 [(match_operand:BITS 1 "nvptx_register_operand" "R")
1124                  (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")
1125                  (match_operand:SI 3 "const_int_operand" "n")]
1126                   UNSPEC_SHUFFLE))]
1127   ""
1128   "%.\\tshfl%S3.b32\\t%0, %1, %2, 31;")
1130 ;; extract parts of a 64 bit object into 2 32-bit ints
1131 (define_insn "unpack<mode>si2"
1132   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1133         (unspec:SI [(match_operand:BITD 2 "nvptx_register_operand" "R")
1134                     (const_int 0)] UNSPEC_BIT_CONV))
1135    (set (match_operand:SI 1 "nvptx_register_operand" "=R")
1136         (unspec:SI [(match_dup 2) (const_int 1)] UNSPEC_BIT_CONV))]
1137   ""
1138   "%.\\tmov.b64\\t{%0,%1}, %2;")
1140 ;; pack 2 32-bit ints into a 64 bit object
1141 (define_insn "packsi<mode>2"
1142   [(set (match_operand:BITD 0 "nvptx_register_operand" "=R")
1143         (unspec:BITD [(match_operand:SI 1 "nvptx_register_operand" "R")
1144                       (match_operand:SI 2 "nvptx_register_operand" "R")]
1145                     UNSPEC_BIT_CONV))]
1146   ""
1147   "%.\\tmov.b64\\t%0, {%1,%2};")
1149 ;; Atomic insns.
1151 (define_expand "atomic_compare_and_swap<mode>"
1152   [(match_operand:SI 0 "nvptx_register_operand")        ;; bool success output
1153    (match_operand:SDIM 1 "nvptx_register_operand")      ;; oldval output
1154    (match_operand:SDIM 2 "memory_operand")              ;; memory
1155    (match_operand:SDIM 3 "nvptx_register_operand")      ;; expected input
1156    (match_operand:SDIM 4 "nvptx_register_operand")      ;; newval input
1157    (match_operand:SI 5 "const_int_operand")             ;; is_weak
1158    (match_operand:SI 6 "const_int_operand")             ;; success model
1159    (match_operand:SI 7 "const_int_operand")]            ;; failure model
1160   ""
1162   emit_insn (gen_atomic_compare_and_swap<mode>_1
1163     (operands[1], operands[2], operands[3], operands[4], operands[6]));
1165   rtx cond = gen_reg_rtx (BImode);
1166   emit_move_insn (cond, gen_rtx_EQ (BImode, operands[1], operands[3]));
1167   emit_insn (gen_sel_truesi (operands[0], cond, GEN_INT (1), GEN_INT (0)));
1168   DONE;
1171 (define_insn "atomic_compare_and_swap<mode>_1"
1172   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1173         (unspec_volatile:SDIM
1174           [(match_operand:SDIM 1 "memory_operand" "+m")
1175            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri")
1176            (match_operand:SDIM 3 "nvptx_nonmemory_operand" "Ri")
1177            (match_operand:SI 4 "const_int_operand")]
1178           UNSPECV_CAS))
1179    (set (match_dup 1)
1180         (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
1181   ""
1182   "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;")
1184 (define_insn "atomic_exchange<mode>"
1185   [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")    ;; output
1186         (unspec_volatile:SDIM
1187           [(match_operand:SDIM 1 "memory_operand" "+m")         ;; memory
1188            (match_operand:SI 3 "const_int_operand")]            ;; model
1189           UNSPECV_XCHG))
1190    (set (match_dup 1)
1191         (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))] ;; input
1192   ""
1193   "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;")
1195 (define_insn "atomic_fetch_add<mode>"
1196   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1197         (unspec_volatile:SDIM
1198           [(plus:SDIM (match_dup 1)
1199                       (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1200            (match_operand:SI 3 "const_int_operand")]            ;; model
1201           UNSPECV_LOCK))
1202    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1203         (match_dup 1))]
1204   ""
1205   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1207 (define_insn "atomic_fetch_addsf"
1208   [(set (match_operand:SF 1 "memory_operand" "+m")
1209         (unspec_volatile:SF
1210          [(plus:SF (match_dup 1)
1211                    (match_operand:SF 2 "nvptx_nonmemory_operand" "RF"))
1212            (match_operand:SI 3 "const_int_operand")]            ;; model
1213           UNSPECV_LOCK))
1214    (set (match_operand:SF 0 "nvptx_register_operand" "=R")
1215         (match_dup 1))]
1216   ""
1217   "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1219 (define_code_iterator any_logic [and ior xor])
1220 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1222 ;; Currently disabled until we add better subtarget support - requires sm_32.
1223 (define_insn "atomic_fetch_<logic><mode>"
1224   [(set (match_operand:SDIM 1 "memory_operand" "+m")
1225         (unspec_volatile:SDIM
1226           [(any_logic:SDIM (match_dup 1)
1227                            (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1228            (match_operand:SI 3 "const_int_operand")]            ;; model
1229           UNSPECV_LOCK))
1230    (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1231         (match_dup 1))]
1232   "0"
1233   "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;")
1235 (define_insn "nvptx_barsync"
1236   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
1237                     UNSPECV_BARSYNC)]
1238   ""
1239   "\\tbar.sync\\t%0;")