1 ;; Machine description for NVPTX.
2 ;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
3 ;; Contributed by Bernd Schmidt <bernds@codesourcery.com>
5 ;; This file is part of GCC.
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)
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" [
46 UNSPEC_FPINT_NEARBYINT
56 (define_c_enum "unspecv" [
62 (define_attr "subregs_ok" "false,true"
63 (const_string "false"))
65 (define_predicate "nvptx_register_operand"
66 (match_code "reg,subreg")
69 return !HARD_REGISTER_P (op);
70 if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
72 if (GET_CODE (op) == SUBREG)
74 return register_operand (op, mode);
77 (define_predicate "nvptx_reg_or_mem_operand"
78 (match_code "mem,reg,subreg")
81 return !HARD_REGISTER_P (op);
82 if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
84 if (GET_CODE (op) == SUBREG)
86 return memory_operand (op, mode) || register_operand (op, mode);
89 ;; Allow symbolic constants.
90 (define_predicate "symbolic_operand"
91 (match_code "symbol_ref,const"))
93 ;; Allow registers or symbolic constants. We can allow frame, arg or stack
94 ;; pointers here since they are actually symbolic constants.
95 (define_predicate "nvptx_register_or_symbolic_operand"
96 (match_code "reg,subreg,symbol_ref,const")
98 if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
100 if (GET_CODE (op) == SUBREG)
104 return register_operand (op, mode);
107 ;; Registers or constants for normal instructions. Does not allow symbolic
109 (define_predicate "nvptx_nonmemory_operand"
110 (match_code "reg,subreg,const_int,const_double")
113 return !HARD_REGISTER_P (op);
114 if (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
116 if (GET_CODE (op) == SUBREG)
118 return nonmemory_operand (op, mode);
121 ;; A source operand for a move instruction. This is the only predicate we use
122 ;; that accepts symbolic constants.
123 (define_predicate "nvptx_general_operand"
124 (match_code "reg,subreg,mem,const,symbol_ref,label_ref,const_int,const_double")
127 return !HARD_REGISTER_P (op);
128 return general_operand (op, mode);
131 ;; A destination operand for a move instruction. This is the only destination
132 ;; predicate that accepts the return register since it requires special handling.
133 (define_predicate "nvptx_nonimmediate_operand"
134 (match_code "reg,subreg,mem")
137 return (op != frame_pointer_rtx
138 && op != arg_pointer_rtx
139 && op != stack_pointer_rtx);
140 return nonimmediate_operand (op, mode);
143 (define_predicate "const_0_operand"
144 (and (match_code "const_int,const_double,const_vector")
145 (match_test "op == CONST0_RTX (GET_MODE (op))")))
147 (define_predicate "global_mem_operand"
148 (and (match_code "mem")
149 (match_test "MEM_ADDR_SPACE (op) == ADDR_SPACE_GLOBAL")))
151 (define_predicate "const_mem_operand"
152 (and (match_code "mem")
153 (match_test "MEM_ADDR_SPACE (op) == ADDR_SPACE_CONST")))
155 (define_predicate "param_mem_operand"
156 (and (match_code "mem")
157 (match_test "MEM_ADDR_SPACE (op) == ADDR_SPACE_PARAM")))
159 (define_predicate "shared_mem_operand"
160 (and (match_code "mem")
161 (match_test "MEM_ADDR_SPACE (op) == ADDR_SPACE_SHARED")))
163 (define_predicate "const0_operand"
164 (and (match_code "const_int")
165 (match_test "op == const0_rtx")))
167 ;; True if this operator is valid for predication.
168 (define_predicate "predicate_operator"
169 (match_code "eq,ne"))
171 (define_predicate "ne_operator"
174 (define_predicate "nvptx_comparison_operator"
175 (match_code "eq,ne,le,ge,lt,gt,leu,geu,ltu,gtu"))
177 (define_predicate "nvptx_float_comparison_operator"
178 (match_code "eq,ne,le,ge,lt,gt,uneq,unle,unge,unlt,ungt,unordered,ordered"))
180 ;; Test for a valid operand for a call instruction.
181 (define_special_predicate "call_insn_operand"
182 (match_code "symbol_ref,reg")
184 if (GET_CODE (op) == SYMBOL_REF)
186 tree decl = SYMBOL_REF_DECL (op);
187 /* This happens for libcalls. */
188 if (decl == NULL_TREE)
190 return TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL;
195 ;; Return true if OP is a call with parallel USEs of the argument
197 (define_predicate "call_operation"
198 (match_code "parallel")
202 for (i = 1; i < XVECLEN (op, 0); i++)
204 rtx elt = XVECEXP (op, 0, i);
205 enum machine_mode mode;
208 if (GET_CODE (elt) != USE
209 || GET_CODE (XEXP (elt, 0)) != REG
210 || XEXP (elt, 0) == frame_pointer_rtx
211 || XEXP (elt, 0) == arg_pointer_rtx
212 || XEXP (elt, 0) == stack_pointer_rtx)
219 (define_constraint "P0"
220 "An integer with the value 0."
221 (and (match_code "const_int")
222 (match_test "ival == 0")))
224 (define_constraint "P1"
225 "An integer with the value 1."
226 (and (match_code "const_int")
227 (match_test "ival == 1")))
229 (define_constraint "Pn"
230 "An integer with the value -1."
231 (and (match_code "const_int")
232 (match_test "ival == -1")))
234 (define_constraint "R"
238 (define_constraint "Ia"
239 "Any integer constant."
240 (and (match_code "const_int") (match_test "true")))
242 (define_mode_iterator QHSDISDFM [QI HI SI DI SF DF])
243 (define_mode_iterator QHSDIM [QI HI SI DI])
244 (define_mode_iterator HSDIM [HI SI DI])
245 (define_mode_iterator BHSDIM [BI HI SI DI])
246 (define_mode_iterator SDIM [SI DI])
247 (define_mode_iterator SDISDFM [SI DI SF DF])
248 (define_mode_iterator QHIM [QI HI])
249 (define_mode_iterator QHSIM [QI HI SI])
250 (define_mode_iterator SDFM [SF DF])
251 (define_mode_iterator SDCM [SC DC])
253 ;; This mode iterator allows :P to be used for patterns that operate on
254 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
255 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
257 ;; We should get away with not defining memory alternatives, since we don't
258 ;; get variables in this mode and pseudos are never spilled.
260 [(set (match_operand:BI 0 "nvptx_register_operand" "=R,R,R")
261 (match_operand:BI 1 "nvptx_nonmemory_operand" "R,P0,Pn"))]
264 %.\\tmov%t0\\t%0, %1;
265 %.\\tsetp.eq.u32\\t%0, 1, 0;
266 %.\\tsetp.eq.u32\\t%0, 1, 1;")
268 (define_insn "*mov<mode>_insn"
269 [(set (match_operand:QHSDIM 0 "nvptx_nonimmediate_operand" "=R,R,R,m")
270 (match_operand:QHSDIM 1 "general_operand" "n,Ri,m,R"))]
271 "!(MEM_P (operands[0])
272 && (!REG_P (operands[1]) || REGNO (operands[1]) <= LAST_VIRTUAL_REGISTER))"
274 if (which_alternative == 2)
275 return "%.\\tld%A1%u1\\t%0, %1;";
276 if (which_alternative == 3)
277 return "%.\\tst%A0%u0\\t%0, %1;";
279 rtx dst = operands[0];
280 rtx src = operands[1];
282 enum machine_mode dst_mode = nvptx_underlying_object_mode (dst);
283 enum machine_mode src_mode = nvptx_underlying_object_mode (src);
284 if (GET_CODE (dst) == SUBREG)
285 dst = SUBREG_REG (dst);
286 if (GET_CODE (src) == SUBREG)
287 src = SUBREG_REG (src);
288 if (src_mode == QImode)
290 if (dst_mode == QImode)
292 if (CONSTANT_P (src))
294 if (GET_MODE_CLASS (dst_mode) != MODE_INT)
295 return "%.\\tmov.b%T0\\t%0, %1;";
297 return "%.\\tmov%t0\\t%0, %1;";
300 /* Special handling for the return register; we allow this register to
301 only occur in the destination of a move insn. */
302 if (REG_P (dst) && REGNO (dst) == NVPTX_RETURN_REGNUM
303 && dst_mode == HImode)
305 if (dst_mode == src_mode)
306 return "%.\\tmov%t0\\t%0, %1;";
307 /* Mode-punning between floating point and integer. */
308 if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
309 return "%.\\tmov.b%T0\\t%0, %1;";
310 return "%.\\tcvt%t0%t1\\t%0, %1;";
312 [(set_attr "subregs_ok" "true")])
314 (define_insn "*mov<mode>_insn"
315 [(set (match_operand:SDFM 0 "nvptx_nonimmediate_operand" "=R,R,m")
316 (match_operand:SDFM 1 "general_operand" "RF,m,R"))]
317 "!(MEM_P (operands[0]) && !REG_P (operands[1]))"
319 if (which_alternative == 1)
320 return "%.\\tld%A1%u0\\t%0, %1;";
321 if (which_alternative == 2)
322 return "%.\\tst%A0%u1\\t%0, %1;";
324 rtx dst = operands[0];
325 rtx src = operands[1];
326 if (GET_CODE (dst) == SUBREG)
327 dst = SUBREG_REG (dst);
328 if (GET_CODE (src) == SUBREG)
329 src = SUBREG_REG (src);
330 enum machine_mode dst_mode = GET_MODE (dst);
331 enum machine_mode src_mode = GET_MODE (src);
332 if (dst_mode == src_mode)
333 return "%.\\tmov%t0\\t%0, %1;";
334 if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
335 return "%.\\tmov.b%T0\\t%0, %1;";
338 [(set_attr "subregs_ok" "true")])
340 (define_insn "load_arg_reg<mode>"
341 [(set (match_operand:QHIM 0 "nvptx_register_operand" "=R")
342 (unspec:QHIM [(match_operand 1 "const_int_operand" "i")]
345 "%.\\tcvt%t0.u32\\t%0, %%ar%1;")
347 (define_insn "load_arg_reg<mode>"
348 [(set (match_operand:SDISDFM 0 "nvptx_register_operand" "=R")
349 (unspec:SDISDFM [(match_operand 1 "const_int_operand" "i")]
352 "%.\\tmov%t0\\t%0, %%ar%1;")
354 (define_expand "mov<mode>"
355 [(set (match_operand:QHSDISDFM 0 "nvptx_nonimmediate_operand" "")
356 (match_operand:QHSDISDFM 1 "general_operand" ""))]
359 operands[1] = nvptx_maybe_convert_symbolic_operand (operands[1]);
360 /* Record the mode of the return register so that we can prevent
361 later optimization passes from changing it. */
362 if (REG_P (operands[0]) && REGNO (operands[0]) == NVPTX_RETURN_REGNUM
365 if (cfun->machine->ret_reg_mode == VOIDmode)
366 cfun->machine->ret_reg_mode = GET_MODE (operands[0]);
368 gcc_assert (cfun->machine->ret_reg_mode == GET_MODE (operands[0]));
371 /* Hard registers are often actually symbolic operands on this target.
372 Don't allow them when storing to memory. */
373 if (MEM_P (operands[0])
374 && (!REG_P (operands[1])
375 || REGNO (operands[1]) <= LAST_VIRTUAL_REGISTER))
377 rtx tmp = gen_reg_rtx (<MODE>mode);
378 emit_move_insn (tmp, operands[1]);
379 emit_move_insn (operands[0], tmp);
382 if (GET_CODE (operands[1]) == SYMBOL_REF)
383 nvptx_record_needed_fndecl (SYMBOL_REF_DECL (operands[1]));
386 (define_insn "highpartscsf2"
387 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
388 (unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
389 UNSPEC_CPLX_HIGHPART))]
391 "%.\\tmov%t0\\t%0, %f1$1;")
393 (define_insn "set_highpartsfsc2"
394 [(set (match_operand:SC 0 "nvptx_register_operand" "+R")
395 (unspec:SC [(match_dup 0)
396 (match_operand:SF 1 "nvptx_register_operand")]
397 UNSPEC_CPLX_HIGHPART))]
399 "%.\\tmov%t1\\t%f0$1, %1;")
401 (define_insn "lowpartscsf2"
402 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
403 (unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
404 UNSPEC_CPLX_LOWPART))]
406 "%.\\tmov%t0\\t%0, %f1$0;")
408 (define_insn "set_lowpartsfsc2"
409 [(set (match_operand:SC 0 "nvptx_register_operand" "+R")
410 (unspec:SC [(match_dup 0)
411 (match_operand:SF 1 "nvptx_register_operand")]
412 UNSPEC_CPLX_LOWPART))]
414 "%.\\tmov%t1\\t%f0$0, %1;")
416 (define_expand "mov<mode>"
417 [(set (match_operand:SDCM 0 "nvptx_nonimmediate_operand" "")
418 (match_operand:SDCM 1 "general_operand" ""))]
421 enum machine_mode submode = <MODE>mode == SCmode ? SFmode : DFmode;
422 int sz = GET_MODE_SIZE (submode);
424 rtx punning_reg = NULL_RTX;
425 rtx copyback = NULL_RTX;
427 if (GET_CODE (operands[0]) == SUBREG)
429 rtx inner = SUBREG_REG (operands[0]);
430 enum machine_mode inner_mode = GET_MODE (inner);
431 int sz2 = GET_MODE_SIZE (inner_mode);
432 gcc_assert (sz2 >= sz);
433 cfun->machine->punning_buffer_size
434 = MAX (cfun->machine->punning_buffer_size, sz2);
435 if (punning_reg == NULL_RTX)
436 punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
437 copyback = gen_move_insn (inner, gen_rtx_MEM (inner_mode, punning_reg));
438 operands[0] = gen_rtx_MEM (<MODE>mode, punning_reg);
440 if (GET_CODE (operands[1]) == SUBREG)
442 rtx inner = SUBREG_REG (operands[1]);
443 enum machine_mode inner_mode = GET_MODE (inner);
444 int sz2 = GET_MODE_SIZE (inner_mode);
445 gcc_assert (sz2 >= sz);
446 cfun->machine->punning_buffer_size
447 = MAX (cfun->machine->punning_buffer_size, sz2);
448 if (punning_reg == NULL_RTX)
449 punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
450 emit_move_insn (gen_rtx_MEM (inner_mode, punning_reg), inner);
451 operands[1] = gen_rtx_MEM (<MODE>mode, punning_reg);
454 if (REG_P (operands[0]) && submode == SFmode)
456 xops[0] = gen_reg_rtx (submode);
457 xops[1] = gen_reg_rtx (submode);
461 xops[0] = gen_lowpart (submode, operands[0]);
462 if (MEM_P (operands[0]))
463 xops[1] = adjust_address_nv (operands[0], submode, sz);
465 xops[1] = gen_highpart (submode, operands[0]);
468 if (REG_P (operands[1]) && submode == SFmode)
470 xops[2] = gen_reg_rtx (submode);
471 xops[3] = gen_reg_rtx (submode);
472 emit_insn (gen_lowpartscsf2 (xops[2], operands[1]));
473 emit_insn (gen_highpartscsf2 (xops[3], operands[1]));
477 xops[2] = gen_lowpart (submode, operands[1]);
478 if (MEM_P (operands[1]))
479 xops[3] = adjust_address_nv (operands[1], submode, sz);
481 xops[3] = gen_highpart (submode, operands[1]);
484 emit_move_insn (xops[0], xops[2]);
485 emit_move_insn (xops[1], xops[3]);
486 if (REG_P (operands[0]) && submode == SFmode)
488 emit_insn (gen_set_lowpartsfsc2 (operands[0], xops[0]));
489 emit_insn (gen_set_highpartsfsc2 (operands[0], xops[1]));
492 emit_insn (copyback);
496 (define_insn "zero_extendqihi2"
497 [(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
498 (zero_extend:HI (match_operand:QI 1 "nvptx_reg_or_mem_operand" "R,m")))]
501 %.\\tcvt.u16.u%T1\\t%0, %1;
502 %.\\tld%A1.u8\\t%0, %1;"
503 [(set_attr "subregs_ok" "true")])
505 (define_insn "zero_extend<mode>si2"
506 [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
507 (zero_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
510 %.\\tcvt.u32.u%T1\\t%0, %1;
511 %.\\tld%A1.u%T1\\t%0, %1;"
512 [(set_attr "subregs_ok" "true")])
514 (define_insn "zero_extend<mode>di2"
515 [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
516 (zero_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
519 %.\\tcvt.u64.u%T1\\t%0, %1;
520 %.\\tld%A1%u1\\t%0, %1;"
521 [(set_attr "subregs_ok" "true")])
523 (define_insn "extend<mode>si2"
524 [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
525 (sign_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
528 %.\\tcvt.s32.s%T1\\t%0, %1;
529 %.\\tld%A1.s%T1\\t%0, %1;"
530 [(set_attr "subregs_ok" "true")])
532 (define_insn "extend<mode>di2"
533 [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
534 (sign_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
537 %.\\tcvt.s64.s%T1\\t%0, %1;
538 %.\\tld%A1.s%T1\\t%0, %1;"
539 [(set_attr "subregs_ok" "true")])
541 (define_insn "trunchiqi2"
542 [(set (match_operand:QI 0 "nvptx_reg_or_mem_operand" "=R,m")
543 (truncate:QI (match_operand:HI 1 "nvptx_register_operand" "R,R")))]
546 %.\\tcvt%t0.u16\\t%0, %1;
547 %.\\tst%A0.u8\\t%0, %1;"
548 [(set_attr "subregs_ok" "true")])
550 (define_insn "truncsi<mode>2"
551 [(set (match_operand:QHIM 0 "nvptx_reg_or_mem_operand" "=R,m")
552 (truncate:QHIM (match_operand:SI 1 "nvptx_register_operand" "R,R")))]
555 %.\\tcvt%t0.u32\\t%0, %1;
556 %.\\tst%A0.u%T0\\t%0, %1;"
557 [(set_attr "subregs_ok" "true")])
559 (define_insn "truncdi<mode>2"
560 [(set (match_operand:QHSIM 0 "nvptx_reg_or_mem_operand" "=R,m")
561 (truncate:QHSIM (match_operand:DI 1 "nvptx_register_operand" "R,R")))]
564 %.\\tcvt%t0.u64\\t%0, %1;
565 %.\\tst%A0.u%T0\\t%0, %1;"
566 [(set_attr "subregs_ok" "true")])
568 ;; Pointer address space conversions
570 (define_int_iterator cvt_code
580 (define_int_attr cvt_name
581 [(UNSPEC_FROM_GLOBAL "from_global")
582 (UNSPEC_FROM_LOCAL "from_local")
583 (UNSPEC_FROM_SHARED "from_shared")
584 (UNSPEC_FROM_CONST "from_const")
585 (UNSPEC_TO_GLOBAL "to_global")
586 (UNSPEC_TO_LOCAL "to_local")
587 (UNSPEC_TO_SHARED "to_shared")
588 (UNSPEC_TO_CONST "to_const")])
590 (define_int_attr cvt_str
591 [(UNSPEC_FROM_GLOBAL ".global")
592 (UNSPEC_FROM_LOCAL ".local")
593 (UNSPEC_FROM_SHARED ".shared")
594 (UNSPEC_FROM_CONST ".const")
595 (UNSPEC_TO_GLOBAL ".to.global")
596 (UNSPEC_TO_LOCAL ".to.local")
597 (UNSPEC_TO_SHARED ".to.shared")
598 (UNSPEC_TO_CONST ".to.const")])
600 (define_insn "convaddr_<cvt_name><mode>"
601 [(set (match_operand:P 0 "nvptx_register_operand" "=R")
602 (unspec:P [(match_operand:P 1 "nvptx_register_or_symbolic_operand" "Rs")] cvt_code))]
604 "%.\\tcvta<cvt_str>%t0\\t%0, %1;")
606 ;; Integer arithmetic
608 (define_insn "add<mode>3"
609 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
610 (plus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
611 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
613 "%.\\tadd%t0\\t%0, %1, %2;")
615 (define_insn "sub<mode>3"
616 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
617 (minus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
618 (match_operand:HSDIM 2 "nvptx_register_operand" "R")))]
620 "%.\\tsub%t0\\t%0, %1, %2;")
622 (define_insn "mul<mode>3"
623 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
624 (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
625 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
627 "%.\\tmul.lo%t0\\t%0, %1, %2;")
629 (define_insn "*mad<mode>3"
630 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
631 (plus:HSDIM (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
632 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri"))
633 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
635 "%.\\tmad.lo%t0\\t%0, %1, %2, %3;")
637 (define_insn "div<mode>3"
638 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
639 (div:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
640 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
642 "%.\\tdiv.s%T0\\t%0, %1, %2;")
644 (define_insn "udiv<mode>3"
645 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
646 (udiv:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
647 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
649 "%.\\tdiv.u%T0\\t%0, %1, %2;")
651 (define_insn "mod<mode>3"
652 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
653 (mod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
654 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
656 "%.\\trem.s%T0\\t%0, %1, %2;")
658 (define_insn "umod<mode>3"
659 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
660 (umod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
661 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
663 "%.\\trem.u%T0\\t%0, %1, %2;")
665 (define_insn "smin<mode>3"
666 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
667 (smin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
668 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
670 "%.\\tmin.s%T0\\t%0, %1, %2;")
672 (define_insn "umin<mode>3"
673 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
674 (umin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
675 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
677 "%.\\tmin.u%T0\\t%0, %1, %2;")
679 (define_insn "smax<mode>3"
680 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
681 (smax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
682 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
684 "%.\\tmax.s%T0\\t%0, %1, %2;")
686 (define_insn "umax<mode>3"
687 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
688 (umax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
689 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
691 "%.\\tmax.u%T0\\t%0, %1, %2;")
693 (define_insn "abs<mode>2"
694 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
695 (abs:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
697 "%.\\tabs.s%T0\\t%0, %1;")
699 (define_insn "neg<mode>2"
700 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
701 (neg:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
703 "%.\\tneg.s%T0\\t%0, %1;")
705 (define_insn "one_cmpl<mode>2"
706 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
707 (not:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
709 "%.\\tnot.b%T0\\t%0, %1;")
711 (define_insn "bitrev<mode>2"
712 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
713 (unspec:SDIM [(match_operand:SDIM 1 "nvptx_register_operand" "R")]
716 "%.\\tbrev.b%T0\\t%0, %1;")
718 (define_insn "clz<mode>2"
719 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
720 (clz:SI (match_operand:SDIM 1 "nvptx_register_operand" "R")))]
722 "%.\\tclz.b%T0\\t%0, %1;")
724 (define_expand "ctz<mode>2"
725 [(set (match_operand:SI 0 "nvptx_register_operand" "")
726 (ctz:SI (match_operand:SDIM 1 "nvptx_register_operand" "")))]
729 rtx tmpreg = gen_reg_rtx (<MODE>mode);
730 emit_insn (gen_bitrev<mode>2 (tmpreg, operands[1]));
731 emit_insn (gen_clz<mode>2 (operands[0], tmpreg));
737 (define_insn "ashl<mode>3"
738 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
739 (ashift:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
740 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
742 "%.\\tshl.b%T0\\t%0, %1, %2;")
744 (define_insn "ashr<mode>3"
745 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
746 (ashiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
747 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
749 "%.\\tshr.s%T0\\t%0, %1, %2;")
751 (define_insn "lshr<mode>3"
752 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
753 (lshiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
754 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
756 "%.\\tshr.u%T0\\t%0, %1, %2;")
758 ;; Logical operations
760 (define_insn "and<mode>3"
761 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
762 (and:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
763 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
765 "%.\\tand.b%T0\\t%0, %1, %2;")
767 (define_insn "ior<mode>3"
768 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
769 (ior:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
770 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
772 "%.\\tor.b%T0\\t%0, %1, %2;")
774 (define_insn "xor<mode>3"
775 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
776 (xor:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
777 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
779 "%.\\txor.b%T0\\t%0, %1, %2;")
781 ;; Comparisons and branches
783 (define_insn "*cmp<mode>"
784 [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
785 (match_operator:BI 1 "nvptx_comparison_operator"
786 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
787 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
789 "%.\\tsetp%c1 %0,%2,%3;")
791 (define_insn "*cmp<mode>"
792 [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
793 (match_operator:BI 1 "nvptx_float_comparison_operator"
794 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
795 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
797 "%.\\tsetp%c1 %0,%2,%3;")
801 (label_ref (match_operand 0 "" "")))]
805 (define_insn "br_true"
807 (if_then_else (ne (match_operand:BI 0 "nvptx_register_operand" "R")
809 (label_ref (match_operand 1 "" ""))
814 (define_insn "br_false"
816 (if_then_else (eq (match_operand:BI 0 "nvptx_register_operand" "R")
818 (label_ref (match_operand 1 "" ""))
823 (define_expand "cbranch<mode>4"
825 (if_then_else (match_operator 0 "nvptx_comparison_operator"
826 [(match_operand:HSDIM 1 "nvptx_register_operand" "")
827 (match_operand:HSDIM 2 "nvptx_register_operand" "")])
828 (label_ref (match_operand 3 "" ""))
832 rtx t = nvptx_expand_compare (operands[0]);
834 operands[1] = XEXP (t, 0);
835 operands[2] = XEXP (t, 1);
838 (define_expand "cbranch<mode>4"
840 (if_then_else (match_operator 0 "nvptx_float_comparison_operator"
841 [(match_operand:SDFM 1 "nvptx_register_operand" "")
842 (match_operand:SDFM 2 "nvptx_register_operand" "")])
843 (label_ref (match_operand 3 "" ""))
847 rtx t = nvptx_expand_compare (operands[0]);
849 operands[1] = XEXP (t, 0);
850 operands[2] = XEXP (t, 1);
853 (define_expand "cbranchbi4"
855 (if_then_else (match_operator 0 "predicate_operator"
856 [(match_operand:BI 1 "nvptx_register_operand" "")
857 (match_operand:BI 2 "const0_operand" "")])
858 (label_ref (match_operand 3 "" ""))
863 ;; Conditional stores
865 (define_insn "setcc_from_bi"
866 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
867 (ne:SI (match_operand:BI 1 "nvptx_register_operand" "R")
870 "%.\\tselp%t0 %0,-1,0,%1;")
872 (define_insn "setcc_int<mode>"
873 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
874 (match_operator:SI 1 "nvptx_comparison_operator"
875 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
876 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
878 "%.\\tset%t0%c1 %0,%2,%3;")
880 (define_insn "setcc_int<mode>"
881 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
882 (match_operator:SI 1 "nvptx_float_comparison_operator"
883 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
884 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
886 "%.\\tset%t0%c1 %0,%2,%3;")
888 (define_insn "setcc_float<mode>"
889 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
890 (match_operator:SF 1 "nvptx_comparison_operator"
891 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
892 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
894 "%.\\tset%t0%c1 %0,%2,%3;")
896 (define_insn "setcc_float<mode>"
897 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
898 (match_operator:SF 1 "nvptx_float_comparison_operator"
899 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
900 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
902 "%.\\tset%t0%c1 %0,%2,%3;")
904 (define_expand "cstorebi4"
905 [(set (match_operand:SI 0 "nvptx_register_operand")
906 (match_operator:SI 1 "ne_operator"
907 [(match_operand:BI 2 "nvptx_register_operand")
908 (match_operand:BI 3 "const0_operand")]))]
912 (define_expand "cstore<mode>4"
913 [(set (match_operand:SI 0 "nvptx_register_operand")
914 (match_operator:SI 1 "nvptx_comparison_operator"
915 [(match_operand:HSDIM 2 "nvptx_register_operand")
916 (match_operand:HSDIM 3 "nvptx_nonmemory_operand")]))]
920 (define_expand "cstore<mode>4"
921 [(set (match_operand:SI 0 "nvptx_register_operand")
922 (match_operator:SI 1 "nvptx_float_comparison_operator"
923 [(match_operand:SDFM 2 "nvptx_register_operand")
924 (match_operand:SDFM 3 "nvptx_nonmemory_operand")]))]
930 (define_insn "call_insn"
931 [(match_parallel 2 "call_operation"
932 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "Rs"))
933 (match_operand 1))])]
936 return nvptx_output_call_insn (insn, NULL_RTX, operands[0]);
939 (define_insn "call_value_insn"
940 [(match_parallel 3 "call_operation"
941 [(set (match_operand 0 "nvptx_register_operand" "=R")
942 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "Rs"))
943 (match_operand 2)))])]
946 return nvptx_output_call_insn (insn, operands[0], operands[1]);
949 (define_expand "call"
950 [(match_operand 0 "" "")]
953 nvptx_expand_call (NULL_RTX, operands[0]);
957 (define_expand "call_value"
958 [(match_operand 0 "" "")
959 (match_operand 1 "" "")]
962 nvptx_expand_call (operands[0], operands[1]);
966 ;; Floating point arithmetic.
968 (define_insn "add<mode>3"
969 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
970 (plus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
971 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
973 "%.\\tadd%t0\\t%0, %1, %2;")
975 (define_insn "sub<mode>3"
976 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
977 (minus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
978 (match_operand:SDFM 2 "nvptx_register_operand" "R")))]
980 "%.\\tsub%t0\\t%0, %1, %2;")
982 (define_insn "mul<mode>3"
983 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
984 (mult:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
985 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
987 "%.\\tmul%t0\\t%0, %1, %2;")
989 (define_insn "fma<mode>4"
990 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
991 (fma:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
992 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
993 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
995 "%.\\tfma%#%t0\\t%0, %1, %2, %3;")
997 (define_insn "div<mode>3"
998 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
999 (div:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1000 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1002 "%.\\tdiv%#%t0\\t%0, %1, %2;")
1004 (define_insn "copysign<mode>3"
1005 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1006 (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")
1007 (match_operand:SDFM 2 "nvptx_register_operand" "R")]
1010 "%.\\tcopysign%t0\\t%0, %2, %1;")
1012 (define_insn "smin<mode>3"
1013 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1014 (smin:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1015 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1017 "%.\\tmin%t0\\t%0, %1, %2;")
1019 (define_insn "smax<mode>3"
1020 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1021 (smax:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1022 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1024 "%.\\tmax%t0\\t%0, %1, %2;")
1026 (define_insn "abs<mode>2"
1027 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1028 (abs:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1030 "%.\\tabs%t0\\t%0, %1;")
1032 (define_insn "neg<mode>2"
1033 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1034 (neg:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1036 "%.\\tneg%t0\\t%0, %1;")
1038 (define_insn "sqrt<mode>2"
1039 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1040 (sqrt:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1042 "%.\\tsqrt%#%t0\\t%0, %1;")
1044 (define_insn "sinsf2"
1045 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1046 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1048 "flag_unsafe_math_optimizations"
1049 "%.\\tsin.approx%t0\\t%0, %1;")
1051 (define_insn "cossf2"
1052 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1053 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1055 "flag_unsafe_math_optimizations"
1056 "%.\\tcos.approx%t0\\t%0, %1;")
1058 (define_insn "log2sf2"
1059 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1060 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1062 "flag_unsafe_math_optimizations"
1063 "%.\\tlg2.approx%t0\\t%0, %1;")
1065 (define_insn "exp2sf2"
1066 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1067 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1069 "flag_unsafe_math_optimizations"
1070 "%.\\tex2.approx%t0\\t%0, %1;")
1072 ;; Conversions involving floating point
1074 (define_insn "extendsfdf2"
1075 [(set (match_operand:DF 0 "nvptx_register_operand" "=R")
1076 (float_extend:DF (match_operand:SF 1 "nvptx_register_operand" "R")))]
1078 "%.\\tcvt%t0%t1\\t%0, %1;")
1080 (define_insn "truncdfsf2"
1081 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1082 (float_truncate:SF (match_operand:DF 1 "nvptx_register_operand" "R")))]
1084 "%.\\tcvt%#%t0%t1\\t%0, %1;")
1086 (define_insn "floatunssi<mode>2"
1087 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1088 (unsigned_float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
1090 "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
1092 (define_insn "floatsi<mode>2"
1093 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1094 (float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
1096 "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
1098 (define_insn "floatunsdi<mode>2"
1099 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1100 (unsigned_float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
1102 "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
1104 (define_insn "floatdi<mode>2"
1105 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1106 (float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
1108 "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
1110 (define_insn "fixuns_trunc<mode>si2"
1111 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1112 (unsigned_fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1114 "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
1116 (define_insn "fix_trunc<mode>si2"
1117 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1118 (fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1120 "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
1122 (define_insn "fixuns_trunc<mode>di2"
1123 [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
1124 (unsigned_fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1126 "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
1128 (define_insn "fix_trunc<mode>di2"
1129 [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
1130 (fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1132 "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
1134 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
1135 UNSPEC_FPINT_CEIL UNSPEC_FPINT_NEARBYINT])
1136 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
1137 (UNSPEC_FPINT_BTRUNC "btrunc")
1138 (UNSPEC_FPINT_CEIL "ceil")
1139 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
1140 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
1141 (UNSPEC_FPINT_BTRUNC ".rzi")
1142 (UNSPEC_FPINT_CEIL ".rpi")
1143 (UNSPEC_FPINT_NEARBYINT "%#i")])
1145 (define_insn "<FPINT:fpint_name><SDFM:mode>2"
1146 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1147 (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
1150 "%.\\tcvt<FPINT:fpint_roundingmode>%t0%t1\\t%0, %1;")
1152 (define_int_iterator FPINT2 [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_CEIL])
1153 (define_int_attr fpint2_name [(UNSPEC_FPINT_FLOOR "lfloor")
1154 (UNSPEC_FPINT_CEIL "lceil")])
1155 (define_int_attr fpint2_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
1156 (UNSPEC_FPINT_CEIL ".rpi")])
1158 (define_insn "<FPINT2:fpint2_name><SDFM:mode><SDIM:mode>2"
1159 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1160 (unspec:SDIM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
1163 "%.\\tcvt<FPINT2:fpint2_roundingmode>.s%T0%t1\\t%0, %1;")
1172 (define_insn "return"
1176 return nvptx_output_return ();
1179 (define_expand "epilogue"
1180 [(clobber (const_int 0))]
1183 emit_jump_insn (gen_return ());
1187 (define_expand "nonlocal_goto"
1188 [(match_operand 0 "" "")
1189 (match_operand 1 "" "")
1190 (match_operand 2 "" "")
1191 (match_operand 3 "" "")]
1194 sorry ("target cannot support nonlocal goto.");
1195 emit_insn (gen_nop ());
1199 (define_expand "nonlocal_goto_receiver"
1203 sorry ("target cannot support nonlocal goto.");
1206 (define_insn "allocate_stack"
1207 [(set (match_operand 0 "nvptx_register_operand" "=R")
1208 (unspec [(match_operand 1 "nvptx_register_operand" "R")]
1211 "%.\\tcall (%0), %%alloca, (%1);")
1213 (define_expand "restore_stack_block"
1214 [(match_operand 0 "register_operand" "")
1215 (match_operand 1 "register_operand" "")]
1221 (define_expand "restore_stack_function"
1222 [(match_operand 0 "register_operand" "")
1223 (match_operand 1 "register_operand" "")]
1230 [(trap_if (const_int 1) (const_int 0))]
1234 (define_insn "trap_if_true"
1235 [(trap_if (ne (match_operand:BI 0 "nvptx_register_operand" "R")
1241 (define_insn "trap_if_false"
1242 [(trap_if (eq (match_operand:BI 0 "nvptx_register_operand" "R")
1248 (define_expand "ctrap<mode>4"
1249 [(trap_if (match_operator 0 "nvptx_comparison_operator"
1250 [(match_operand:SDIM 1 "nvptx_register_operand")
1251 (match_operand:SDIM 2 "nvptx_nonmemory_operand")])
1252 (match_operand 3 "const_0_operand"))]
1255 rtx t = nvptx_expand_compare (operands[0]);
1256 emit_insn (gen_trap_if_true (t));
1260 (define_insn "*oacc_ntid_insn"
1261 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1262 (unspec:SI [(match_operand:SI 1 "const_int_operand" "n")] UNSPEC_NTID))]
1264 "%.\\tmov.u32 %0, %%ntid%d1;")
1266 (define_expand "oacc_ntid"
1267 [(set (match_operand:SI 0 "nvptx_register_operand" "")
1268 (unspec:SI [(match_operand:SI 1 "const_int_operand" "")] UNSPEC_NTID))]
1271 if (INTVAL (operands[1]) < 0 || INTVAL (operands[1]) > 2)
1275 (define_insn "*oacc_tid_insn"
1276 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1277 (unspec:SI [(match_operand:SI 1 "const_int_operand" "n")] UNSPEC_TID))]
1279 "%.\\tmov.u32 %0, %%tid%d1;")
1281 (define_expand "oacc_tid"
1282 [(set (match_operand:SI 0 "nvptx_register_operand" "")
1283 (unspec:SI [(match_operand:SI 1 "const_int_operand" "")] UNSPEC_TID))]
1286 if (INTVAL (operands[1]) < 0 || INTVAL (operands[1]) > 2)
1292 (define_expand "atomic_compare_and_swap<mode>"
1293 [(match_operand:SI 0 "nvptx_register_operand") ;; bool success output
1294 (match_operand:SDIM 1 "nvptx_register_operand") ;; oldval output
1295 (match_operand:SDIM 2 "memory_operand") ;; memory
1296 (match_operand:SDIM 3 "nvptx_register_operand") ;; expected input
1297 (match_operand:SDIM 4 "nvptx_register_operand") ;; newval input
1298 (match_operand:SI 5 "const_int_operand") ;; is_weak
1299 (match_operand:SI 6 "const_int_operand") ;; success model
1300 (match_operand:SI 7 "const_int_operand")] ;; failure model
1303 emit_insn (gen_atomic_compare_and_swap<mode>_1 (operands[1], operands[2], operands[3],
1304 operands[4], operands[6]));
1306 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
1307 emit_insn (gen_cstore<mode>4 (tmp,
1308 gen_rtx_EQ (SImode, operands[1], operands[3]),
1309 operands[1], operands[3]));
1310 emit_insn (gen_andsi3 (operands[0], tmp, GEN_INT (1)));
1314 (define_insn "atomic_compare_and_swap<mode>_1"
1315 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1316 (unspec_volatile:SDIM
1317 [(match_operand:SDIM 1 "memory_operand" "+m")
1318 (match_operand:SDIM 2 "nvptx_register_operand" "R")
1319 (match_operand:SDIM 3 "nvptx_register_operand" "R")
1320 (match_operand:SI 4 "const_int_operand")]
1323 (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
1325 "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;")
1327 (define_insn "atomic_exchange<mode>"
1328 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R") ;; output
1329 (unspec_volatile:SDIM
1330 [(match_operand:SDIM 1 "memory_operand" "+m") ;; memory
1331 (match_operand:SI 3 "const_int_operand")] ;; model
1334 (match_operand:SDIM 2 "nvptx_register_operand" "R"))] ;; input
1336 "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;")
1338 (define_insn "atomic_fetch_add<mode>"
1339 [(set (match_operand:SDIM 1 "memory_operand" "+m")
1340 (unspec_volatile:SDIM
1341 [(plus:SDIM (match_dup 1)
1342 (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1343 (match_operand:SI 3 "const_int_operand")] ;; model
1345 (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1348 "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1350 (define_insn "atomic_fetch_addsf"
1351 [(set (match_operand:SF 1 "memory_operand" "+m")
1353 [(plus:SF (match_dup 1)
1354 (match_operand:SF 2 "nvptx_nonmemory_operand" "RF"))
1355 (match_operand:SI 3 "const_int_operand")] ;; model
1357 (set (match_operand:SF 0 "nvptx_register_operand" "=R")
1360 "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1362 (define_code_iterator any_logic [and ior xor])
1363 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1365 ;; Currently disabled until we add better subtarget support - requires sm_32.
1366 (define_insn "atomic_fetch_<logic><mode>"
1367 [(set (match_operand:SDIM 1 "memory_operand" "+m")
1368 (unspec_volatile:SDIM
1369 [(any_logic:SDIM (match_dup 1)
1370 (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1371 (match_operand:SI 3 "const_int_operand")] ;; model
1373 (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1376 "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;")