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);
206 if (GET_CODE (elt) != USE
207 || GET_CODE (XEXP (elt, 0)) != REG
208 || XEXP (elt, 0) == frame_pointer_rtx
209 || XEXP (elt, 0) == arg_pointer_rtx
210 || XEXP (elt, 0) == stack_pointer_rtx)
216 (define_constraint "P0"
217 "An integer with the value 0."
218 (and (match_code "const_int")
219 (match_test "ival == 0")))
221 (define_constraint "P1"
222 "An integer with the value 1."
223 (and (match_code "const_int")
224 (match_test "ival == 1")))
226 (define_constraint "Pn"
227 "An integer with the value -1."
228 (and (match_code "const_int")
229 (match_test "ival == -1")))
231 (define_constraint "R"
235 (define_constraint "Ia"
236 "Any integer constant."
237 (and (match_code "const_int") (match_test "true")))
239 (define_mode_iterator QHSDISDFM [QI HI SI DI SF DF])
240 (define_mode_iterator QHSDIM [QI HI SI DI])
241 (define_mode_iterator HSDIM [HI SI DI])
242 (define_mode_iterator BHSDIM [BI HI SI DI])
243 (define_mode_iterator SDIM [SI DI])
244 (define_mode_iterator SDISDFM [SI DI SF DF])
245 (define_mode_iterator QHIM [QI HI])
246 (define_mode_iterator QHSIM [QI HI SI])
247 (define_mode_iterator SDFM [SF DF])
248 (define_mode_iterator SDCM [SC DC])
250 ;; This mode iterator allows :P to be used for patterns that operate on
251 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
252 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
254 ;; We should get away with not defining memory alternatives, since we don't
255 ;; get variables in this mode and pseudos are never spilled.
257 [(set (match_operand:BI 0 "nvptx_register_operand" "=R,R,R")
258 (match_operand:BI 1 "nvptx_nonmemory_operand" "R,P0,Pn"))]
261 %.\\tmov%t0\\t%0, %1;
262 %.\\tsetp.eq.u32\\t%0, 1, 0;
263 %.\\tsetp.eq.u32\\t%0, 1, 1;")
265 (define_insn "*mov<mode>_insn"
266 [(set (match_operand:QHSDIM 0 "nvptx_nonimmediate_operand" "=R,R,R,m")
267 (match_operand:QHSDIM 1 "general_operand" "n,Ri,m,R"))]
268 "!(MEM_P (operands[0])
269 && (!REG_P (operands[1]) || REGNO (operands[1]) <= LAST_VIRTUAL_REGISTER))"
271 if (which_alternative == 2)
272 return "%.\\tld%A1%u1\\t%0, %1;";
273 if (which_alternative == 3)
274 return "%.\\tst%A0%u0\\t%0, %1;";
276 rtx dst = operands[0];
277 rtx src = operands[1];
279 enum machine_mode dst_mode = nvptx_underlying_object_mode (dst);
280 enum machine_mode src_mode = nvptx_underlying_object_mode (src);
281 if (GET_CODE (dst) == SUBREG)
282 dst = SUBREG_REG (dst);
283 if (GET_CODE (src) == SUBREG)
284 src = SUBREG_REG (src);
285 if (src_mode == QImode)
287 if (dst_mode == QImode)
289 if (CONSTANT_P (src))
291 if (GET_MODE_CLASS (dst_mode) != MODE_INT)
292 return "%.\\tmov.b%T0\\t%0, %1;";
294 return "%.\\tmov%t0\\t%0, %1;";
297 /* Special handling for the return register; we allow this register to
298 only occur in the destination of a move insn. */
299 if (REG_P (dst) && REGNO (dst) == NVPTX_RETURN_REGNUM
300 && dst_mode == HImode)
302 if (dst_mode == src_mode)
303 return "%.\\tmov%t0\\t%0, %1;";
304 /* Mode-punning between floating point and integer. */
305 if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
306 return "%.\\tmov.b%T0\\t%0, %1;";
307 return "%.\\tcvt%t0%t1\\t%0, %1;";
309 [(set_attr "subregs_ok" "true")])
311 (define_insn "*mov<mode>_insn"
312 [(set (match_operand:SDFM 0 "nvptx_nonimmediate_operand" "=R,R,m")
313 (match_operand:SDFM 1 "general_operand" "RF,m,R"))]
314 "!(MEM_P (operands[0]) && !REG_P (operands[1]))"
316 if (which_alternative == 1)
317 return "%.\\tld%A1%u0\\t%0, %1;";
318 if (which_alternative == 2)
319 return "%.\\tst%A0%u1\\t%0, %1;";
321 rtx dst = operands[0];
322 rtx src = operands[1];
323 if (GET_CODE (dst) == SUBREG)
324 dst = SUBREG_REG (dst);
325 if (GET_CODE (src) == SUBREG)
326 src = SUBREG_REG (src);
327 enum machine_mode dst_mode = GET_MODE (dst);
328 enum machine_mode src_mode = GET_MODE (src);
329 if (dst_mode == src_mode)
330 return "%.\\tmov%t0\\t%0, %1;";
331 if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
332 return "%.\\tmov.b%T0\\t%0, %1;";
335 [(set_attr "subregs_ok" "true")])
337 (define_insn "load_arg_reg<mode>"
338 [(set (match_operand:QHIM 0 "nvptx_register_operand" "=R")
339 (unspec:QHIM [(match_operand 1 "const_int_operand" "i")]
342 "%.\\tcvt%t0.u32\\t%0, %%ar%1;")
344 (define_insn "load_arg_reg<mode>"
345 [(set (match_operand:SDISDFM 0 "nvptx_register_operand" "=R")
346 (unspec:SDISDFM [(match_operand 1 "const_int_operand" "i")]
349 "%.\\tmov%t0\\t%0, %%ar%1;")
351 (define_expand "mov<mode>"
352 [(set (match_operand:QHSDISDFM 0 "nvptx_nonimmediate_operand" "")
353 (match_operand:QHSDISDFM 1 "general_operand" ""))]
356 operands[1] = nvptx_maybe_convert_symbolic_operand (operands[1]);
357 /* Record the mode of the return register so that we can prevent
358 later optimization passes from changing it. */
359 if (REG_P (operands[0]) && REGNO (operands[0]) == NVPTX_RETURN_REGNUM
362 if (cfun->machine->ret_reg_mode == VOIDmode)
363 cfun->machine->ret_reg_mode = GET_MODE (operands[0]);
365 gcc_assert (cfun->machine->ret_reg_mode == GET_MODE (operands[0]));
368 /* Hard registers are often actually symbolic operands on this target.
369 Don't allow them when storing to memory. */
370 if (MEM_P (operands[0])
371 && (!REG_P (operands[1])
372 || REGNO (operands[1]) <= LAST_VIRTUAL_REGISTER))
374 rtx tmp = gen_reg_rtx (<MODE>mode);
375 emit_move_insn (tmp, operands[1]);
376 emit_move_insn (operands[0], tmp);
379 if (GET_CODE (operands[1]) == SYMBOL_REF)
380 nvptx_record_needed_fndecl (SYMBOL_REF_DECL (operands[1]));
383 (define_insn "highpartscsf2"
384 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
385 (unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
386 UNSPEC_CPLX_HIGHPART))]
388 "%.\\tmov%t0\\t%0, %f1$1;")
390 (define_insn "set_highpartsfsc2"
391 [(set (match_operand:SC 0 "nvptx_register_operand" "+R")
392 (unspec:SC [(match_dup 0)
393 (match_operand:SF 1 "nvptx_register_operand")]
394 UNSPEC_CPLX_HIGHPART))]
396 "%.\\tmov%t1\\t%f0$1, %1;")
398 (define_insn "lowpartscsf2"
399 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
400 (unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
401 UNSPEC_CPLX_LOWPART))]
403 "%.\\tmov%t0\\t%0, %f1$0;")
405 (define_insn "set_lowpartsfsc2"
406 [(set (match_operand:SC 0 "nvptx_register_operand" "+R")
407 (unspec:SC [(match_dup 0)
408 (match_operand:SF 1 "nvptx_register_operand")]
409 UNSPEC_CPLX_LOWPART))]
411 "%.\\tmov%t1\\t%f0$0, %1;")
413 (define_expand "mov<mode>"
414 [(set (match_operand:SDCM 0 "nvptx_nonimmediate_operand" "")
415 (match_operand:SDCM 1 "general_operand" ""))]
418 enum machine_mode submode = <MODE>mode == SCmode ? SFmode : DFmode;
419 int sz = GET_MODE_SIZE (submode);
421 rtx punning_reg = NULL_RTX;
422 rtx copyback = NULL_RTX;
424 if (GET_CODE (operands[0]) == SUBREG)
426 rtx inner = SUBREG_REG (operands[0]);
427 enum machine_mode inner_mode = GET_MODE (inner);
428 int sz2 = GET_MODE_SIZE (inner_mode);
429 gcc_assert (sz2 >= sz);
430 cfun->machine->punning_buffer_size
431 = MAX (cfun->machine->punning_buffer_size, sz2);
432 if (punning_reg == NULL_RTX)
433 punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
434 copyback = gen_move_insn (inner, gen_rtx_MEM (inner_mode, punning_reg));
435 operands[0] = gen_rtx_MEM (<MODE>mode, punning_reg);
437 if (GET_CODE (operands[1]) == SUBREG)
439 rtx inner = SUBREG_REG (operands[1]);
440 enum machine_mode inner_mode = GET_MODE (inner);
441 int sz2 = GET_MODE_SIZE (inner_mode);
442 gcc_assert (sz2 >= sz);
443 cfun->machine->punning_buffer_size
444 = MAX (cfun->machine->punning_buffer_size, sz2);
445 if (punning_reg == NULL_RTX)
446 punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
447 emit_move_insn (gen_rtx_MEM (inner_mode, punning_reg), inner);
448 operands[1] = gen_rtx_MEM (<MODE>mode, punning_reg);
451 if (REG_P (operands[0]) && submode == SFmode)
453 xops[0] = gen_reg_rtx (submode);
454 xops[1] = gen_reg_rtx (submode);
458 xops[0] = gen_lowpart (submode, operands[0]);
459 if (MEM_P (operands[0]))
460 xops[1] = adjust_address_nv (operands[0], submode, sz);
462 xops[1] = gen_highpart (submode, operands[0]);
465 if (REG_P (operands[1]) && submode == SFmode)
467 xops[2] = gen_reg_rtx (submode);
468 xops[3] = gen_reg_rtx (submode);
469 emit_insn (gen_lowpartscsf2 (xops[2], operands[1]));
470 emit_insn (gen_highpartscsf2 (xops[3], operands[1]));
474 xops[2] = gen_lowpart (submode, operands[1]);
475 if (MEM_P (operands[1]))
476 xops[3] = adjust_address_nv (operands[1], submode, sz);
478 xops[3] = gen_highpart (submode, operands[1]);
481 emit_move_insn (xops[0], xops[2]);
482 emit_move_insn (xops[1], xops[3]);
483 if (REG_P (operands[0]) && submode == SFmode)
485 emit_insn (gen_set_lowpartsfsc2 (operands[0], xops[0]));
486 emit_insn (gen_set_highpartsfsc2 (operands[0], xops[1]));
489 emit_insn (copyback);
493 (define_insn "zero_extendqihi2"
494 [(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
495 (zero_extend:HI (match_operand:QI 1 "nvptx_reg_or_mem_operand" "R,m")))]
498 %.\\tcvt.u16.u%T1\\t%0, %1;
499 %.\\tld%A1.u8\\t%0, %1;"
500 [(set_attr "subregs_ok" "true")])
502 (define_insn "zero_extend<mode>si2"
503 [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
504 (zero_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
507 %.\\tcvt.u32.u%T1\\t%0, %1;
508 %.\\tld%A1.u%T1\\t%0, %1;"
509 [(set_attr "subregs_ok" "true")])
511 (define_insn "zero_extend<mode>di2"
512 [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
513 (zero_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
516 %.\\tcvt.u64.u%T1\\t%0, %1;
517 %.\\tld%A1%u1\\t%0, %1;"
518 [(set_attr "subregs_ok" "true")])
520 (define_insn "extend<mode>si2"
521 [(set (match_operand:SI 0 "nvptx_register_operand" "=R,R")
522 (sign_extend:SI (match_operand:QHIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
525 %.\\tcvt.s32.s%T1\\t%0, %1;
526 %.\\tld%A1.s%T1\\t%0, %1;"
527 [(set_attr "subregs_ok" "true")])
529 (define_insn "extend<mode>di2"
530 [(set (match_operand:DI 0 "nvptx_register_operand" "=R,R")
531 (sign_extend:DI (match_operand:QHSIM 1 "nvptx_reg_or_mem_operand" "R,m")))]
534 %.\\tcvt.s64.s%T1\\t%0, %1;
535 %.\\tld%A1.s%T1\\t%0, %1;"
536 [(set_attr "subregs_ok" "true")])
538 (define_insn "trunchiqi2"
539 [(set (match_operand:QI 0 "nvptx_reg_or_mem_operand" "=R,m")
540 (truncate:QI (match_operand:HI 1 "nvptx_register_operand" "R,R")))]
543 %.\\tcvt%t0.u16\\t%0, %1;
544 %.\\tst%A0.u8\\t%0, %1;"
545 [(set_attr "subregs_ok" "true")])
547 (define_insn "truncsi<mode>2"
548 [(set (match_operand:QHIM 0 "nvptx_reg_or_mem_operand" "=R,m")
549 (truncate:QHIM (match_operand:SI 1 "nvptx_register_operand" "R,R")))]
552 %.\\tcvt%t0.u32\\t%0, %1;
553 %.\\tst%A0.u%T0\\t%0, %1;"
554 [(set_attr "subregs_ok" "true")])
556 (define_insn "truncdi<mode>2"
557 [(set (match_operand:QHSIM 0 "nvptx_reg_or_mem_operand" "=R,m")
558 (truncate:QHSIM (match_operand:DI 1 "nvptx_register_operand" "R,R")))]
561 %.\\tcvt%t0.u64\\t%0, %1;
562 %.\\tst%A0.u%T0\\t%0, %1;"
563 [(set_attr "subregs_ok" "true")])
565 ;; Pointer address space conversions
567 (define_int_iterator cvt_code
577 (define_int_attr cvt_name
578 [(UNSPEC_FROM_GLOBAL "from_global")
579 (UNSPEC_FROM_LOCAL "from_local")
580 (UNSPEC_FROM_SHARED "from_shared")
581 (UNSPEC_FROM_CONST "from_const")
582 (UNSPEC_TO_GLOBAL "to_global")
583 (UNSPEC_TO_LOCAL "to_local")
584 (UNSPEC_TO_SHARED "to_shared")
585 (UNSPEC_TO_CONST "to_const")])
587 (define_int_attr cvt_str
588 [(UNSPEC_FROM_GLOBAL ".global")
589 (UNSPEC_FROM_LOCAL ".local")
590 (UNSPEC_FROM_SHARED ".shared")
591 (UNSPEC_FROM_CONST ".const")
592 (UNSPEC_TO_GLOBAL ".to.global")
593 (UNSPEC_TO_LOCAL ".to.local")
594 (UNSPEC_TO_SHARED ".to.shared")
595 (UNSPEC_TO_CONST ".to.const")])
597 (define_insn "convaddr_<cvt_name><mode>"
598 [(set (match_operand:P 0 "nvptx_register_operand" "=R")
599 (unspec:P [(match_operand:P 1 "nvptx_register_or_symbolic_operand" "Rs")] cvt_code))]
601 "%.\\tcvta<cvt_str>%t0\\t%0, %1;")
603 ;; Integer arithmetic
605 (define_insn "add<mode>3"
606 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
607 (plus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
608 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
610 "%.\\tadd%t0\\t%0, %1, %2;")
612 (define_insn "sub<mode>3"
613 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
614 (minus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
615 (match_operand:HSDIM 2 "nvptx_register_operand" "R")))]
617 "%.\\tsub%t0\\t%0, %1, %2;")
619 (define_insn "mul<mode>3"
620 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
621 (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
622 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
624 "%.\\tmul.lo%t0\\t%0, %1, %2;")
626 (define_insn "*mad<mode>3"
627 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
628 (plus:HSDIM (mult:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
629 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri"))
630 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
632 "%.\\tmad.lo%t0\\t%0, %1, %2, %3;")
634 (define_insn "div<mode>3"
635 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
636 (div:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
637 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
639 "%.\\tdiv.s%T0\\t%0, %1, %2;")
641 (define_insn "udiv<mode>3"
642 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
643 (udiv:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
644 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
646 "%.\\tdiv.u%T0\\t%0, %1, %2;")
648 (define_insn "mod<mode>3"
649 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
650 (mod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
651 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
653 "%.\\trem.s%T0\\t%0, %1, %2;")
655 (define_insn "umod<mode>3"
656 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
657 (umod:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "Ri")
658 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
660 "%.\\trem.u%T0\\t%0, %1, %2;")
662 (define_insn "smin<mode>3"
663 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
664 (smin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
665 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
667 "%.\\tmin.s%T0\\t%0, %1, %2;")
669 (define_insn "umin<mode>3"
670 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
671 (umin:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
672 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
674 "%.\\tmin.u%T0\\t%0, %1, %2;")
676 (define_insn "smax<mode>3"
677 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
678 (smax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
679 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
681 "%.\\tmax.s%T0\\t%0, %1, %2;")
683 (define_insn "umax<mode>3"
684 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
685 (umax:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
686 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
688 "%.\\tmax.u%T0\\t%0, %1, %2;")
690 (define_insn "abs<mode>2"
691 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
692 (abs:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
694 "%.\\tabs.s%T0\\t%0, %1;")
696 (define_insn "neg<mode>2"
697 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
698 (neg:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
700 "%.\\tneg.s%T0\\t%0, %1;")
702 (define_insn "one_cmpl<mode>2"
703 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
704 (not:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")))]
706 "%.\\tnot.b%T0\\t%0, %1;")
708 (define_insn "bitrev<mode>2"
709 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
710 (unspec:SDIM [(match_operand:SDIM 1 "nvptx_register_operand" "R")]
713 "%.\\tbrev.b%T0\\t%0, %1;")
715 (define_insn "clz<mode>2"
716 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
717 (clz:SI (match_operand:SDIM 1 "nvptx_register_operand" "R")))]
719 "%.\\tclz.b%T0\\t%0, %1;")
721 (define_expand "ctz<mode>2"
722 [(set (match_operand:SI 0 "nvptx_register_operand" "")
723 (ctz:SI (match_operand:SDIM 1 "nvptx_register_operand" "")))]
726 rtx tmpreg = gen_reg_rtx (<MODE>mode);
727 emit_insn (gen_bitrev<mode>2 (tmpreg, operands[1]));
728 emit_insn (gen_clz<mode>2 (operands[0], tmpreg));
734 (define_insn "ashl<mode>3"
735 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
736 (ashift:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
737 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
739 "%.\\tshl.b%T0\\t%0, %1, %2;")
741 (define_insn "ashr<mode>3"
742 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
743 (ashiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
744 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
746 "%.\\tshr.s%T0\\t%0, %1, %2;")
748 (define_insn "lshr<mode>3"
749 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
750 (lshiftrt:SDIM (match_operand:SDIM 1 "nvptx_register_operand" "R")
751 (match_operand:SI 2 "nvptx_nonmemory_operand" "Ri")))]
753 "%.\\tshr.u%T0\\t%0, %1, %2;")
755 ;; Logical operations
757 (define_insn "and<mode>3"
758 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
759 (and:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
760 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
762 "%.\\tand.b%T0\\t%0, %1, %2;")
764 (define_insn "ior<mode>3"
765 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
766 (ior:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
767 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
769 "%.\\tor.b%T0\\t%0, %1, %2;")
771 (define_insn "xor<mode>3"
772 [(set (match_operand:BHSDIM 0 "nvptx_register_operand" "=R")
773 (xor:BHSDIM (match_operand:BHSDIM 1 "nvptx_register_operand" "R")
774 (match_operand:BHSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
776 "%.\\txor.b%T0\\t%0, %1, %2;")
778 ;; Comparisons and branches
780 (define_insn "*cmp<mode>"
781 [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
782 (match_operator:BI 1 "nvptx_comparison_operator"
783 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
784 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
786 "%.\\tsetp%c1 %0,%2,%3;")
788 (define_insn "*cmp<mode>"
789 [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
790 (match_operator:BI 1 "nvptx_float_comparison_operator"
791 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
792 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
794 "%.\\tsetp%c1 %0,%2,%3;")
798 (label_ref (match_operand 0 "" "")))]
802 (define_insn "br_true"
804 (if_then_else (ne (match_operand:BI 0 "nvptx_register_operand" "R")
806 (label_ref (match_operand 1 "" ""))
811 (define_insn "br_false"
813 (if_then_else (eq (match_operand:BI 0 "nvptx_register_operand" "R")
815 (label_ref (match_operand 1 "" ""))
820 (define_expand "cbranch<mode>4"
822 (if_then_else (match_operator 0 "nvptx_comparison_operator"
823 [(match_operand:HSDIM 1 "nvptx_register_operand" "")
824 (match_operand:HSDIM 2 "nvptx_register_operand" "")])
825 (label_ref (match_operand 3 "" ""))
829 rtx t = nvptx_expand_compare (operands[0]);
831 operands[1] = XEXP (t, 0);
832 operands[2] = XEXP (t, 1);
835 (define_expand "cbranch<mode>4"
837 (if_then_else (match_operator 0 "nvptx_float_comparison_operator"
838 [(match_operand:SDFM 1 "nvptx_register_operand" "")
839 (match_operand:SDFM 2 "nvptx_register_operand" "")])
840 (label_ref (match_operand 3 "" ""))
844 rtx t = nvptx_expand_compare (operands[0]);
846 operands[1] = XEXP (t, 0);
847 operands[2] = XEXP (t, 1);
850 (define_expand "cbranchbi4"
852 (if_then_else (match_operator 0 "predicate_operator"
853 [(match_operand:BI 1 "nvptx_register_operand" "")
854 (match_operand:BI 2 "const0_operand" "")])
855 (label_ref (match_operand 3 "" ""))
860 ;; Conditional stores
862 (define_insn "setcc_from_bi"
863 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
864 (ne:SI (match_operand:BI 1 "nvptx_register_operand" "R")
867 "%.\\tselp%t0 %0,-1,0,%1;")
869 (define_insn "sel_true<mode>"
870 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
872 (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
873 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
874 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
876 "%.\\tselp%t0\\t%0, %2, %3, %1;")
878 (define_insn "sel_true<mode>"
879 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
881 (ne (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
882 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
883 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
885 "%.\\tselp%t0\\t%0, %2, %3, %1;")
887 (define_insn "sel_false<mode>"
888 [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
890 (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
891 (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")
892 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")))]
894 "%.\\tselp%t0\\t%0, %3, %2, %1;")
896 (define_insn "sel_false<mode>"
897 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
899 (eq (match_operand:BI 1 "nvptx_register_operand" "R") (const_int 0))
900 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
901 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
903 "%.\\tselp%t0\\t%0, %3, %2, %1;")
905 (define_insn "setcc_int<mode>"
906 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
907 (match_operator:SI 1 "nvptx_comparison_operator"
908 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
909 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
911 "%.\\tset%t0%c1 %0,%2,%3;")
913 (define_insn "setcc_int<mode>"
914 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
915 (match_operator:SI 1 "nvptx_float_comparison_operator"
916 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
917 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
919 "%.\\tset%t0%c1 %0,%2,%3;")
921 (define_insn "setcc_float<mode>"
922 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
923 (match_operator:SF 1 "nvptx_comparison_operator"
924 [(match_operand:HSDIM 2 "nvptx_register_operand" "R")
925 (match_operand:HSDIM 3 "nvptx_nonmemory_operand" "Ri")]))]
927 "%.\\tset%t0%c1 %0,%2,%3;")
929 (define_insn "setcc_float<mode>"
930 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
931 (match_operator:SF 1 "nvptx_float_comparison_operator"
932 [(match_operand:SDFM 2 "nvptx_register_operand" "R")
933 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")]))]
935 "%.\\tset%t0%c1 %0,%2,%3;")
937 (define_expand "cstorebi4"
938 [(set (match_operand:SI 0 "nvptx_register_operand")
939 (match_operator:SI 1 "ne_operator"
940 [(match_operand:BI 2 "nvptx_register_operand")
941 (match_operand:BI 3 "const0_operand")]))]
945 (define_expand "cstore<mode>4"
946 [(set (match_operand:SI 0 "nvptx_register_operand")
947 (match_operator:SI 1 "nvptx_comparison_operator"
948 [(match_operand:HSDIM 2 "nvptx_register_operand")
949 (match_operand:HSDIM 3 "nvptx_nonmemory_operand")]))]
953 (define_expand "cstore<mode>4"
954 [(set (match_operand:SI 0 "nvptx_register_operand")
955 (match_operator:SI 1 "nvptx_float_comparison_operator"
956 [(match_operand:SDFM 2 "nvptx_register_operand")
957 (match_operand:SDFM 3 "nvptx_nonmemory_operand")]))]
963 (define_insn "call_insn"
964 [(match_parallel 2 "call_operation"
965 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "Rs"))
966 (match_operand 1))])]
969 return nvptx_output_call_insn (insn, NULL_RTX, operands[0]);
972 (define_insn "call_value_insn"
973 [(match_parallel 3 "call_operation"
974 [(set (match_operand 0 "nvptx_register_operand" "=R")
975 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "Rs"))
976 (match_operand 2)))])]
979 return nvptx_output_call_insn (insn, operands[0], operands[1]);
982 (define_expand "call"
983 [(match_operand 0 "" "")]
986 nvptx_expand_call (NULL_RTX, operands[0]);
990 (define_expand "call_value"
991 [(match_operand 0 "" "")
992 (match_operand 1 "" "")]
995 nvptx_expand_call (operands[0], operands[1]);
999 ;; Floating point arithmetic.
1001 (define_insn "add<mode>3"
1002 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1003 (plus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1004 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1006 "%.\\tadd%t0\\t%0, %1, %2;")
1008 (define_insn "sub<mode>3"
1009 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1010 (minus:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1011 (match_operand:SDFM 2 "nvptx_register_operand" "R")))]
1013 "%.\\tsub%t0\\t%0, %1, %2;")
1015 (define_insn "mul<mode>3"
1016 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1017 (mult:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1018 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1020 "%.\\tmul%t0\\t%0, %1, %2;")
1022 (define_insn "fma<mode>4"
1023 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1024 (fma:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1025 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")
1026 (match_operand:SDFM 3 "nvptx_nonmemory_operand" "RF")))]
1028 "%.\\tfma%#%t0\\t%0, %1, %2, %3;")
1030 (define_insn "div<mode>3"
1031 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1032 (div:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1033 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1035 "%.\\tdiv%#%t0\\t%0, %1, %2;")
1037 (define_insn "copysign<mode>3"
1038 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1039 (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")
1040 (match_operand:SDFM 2 "nvptx_register_operand" "R")]
1043 "%.\\tcopysign%t0\\t%0, %2, %1;")
1045 (define_insn "smin<mode>3"
1046 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1047 (smin:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1048 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1050 "%.\\tmin%t0\\t%0, %1, %2;")
1052 (define_insn "smax<mode>3"
1053 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1054 (smax:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")
1055 (match_operand:SDFM 2 "nvptx_nonmemory_operand" "RF")))]
1057 "%.\\tmax%t0\\t%0, %1, %2;")
1059 (define_insn "abs<mode>2"
1060 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1061 (abs:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1063 "%.\\tabs%t0\\t%0, %1;")
1065 (define_insn "neg<mode>2"
1066 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1067 (neg:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1069 "%.\\tneg%t0\\t%0, %1;")
1071 (define_insn "sqrt<mode>2"
1072 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1073 (sqrt:SDFM (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1075 "%.\\tsqrt%#%t0\\t%0, %1;")
1077 (define_insn "sinsf2"
1078 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1079 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1081 "flag_unsafe_math_optimizations"
1082 "%.\\tsin.approx%t0\\t%0, %1;")
1084 (define_insn "cossf2"
1085 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1086 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1088 "flag_unsafe_math_optimizations"
1089 "%.\\tcos.approx%t0\\t%0, %1;")
1091 (define_insn "log2sf2"
1092 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1093 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1095 "flag_unsafe_math_optimizations"
1096 "%.\\tlg2.approx%t0\\t%0, %1;")
1098 (define_insn "exp2sf2"
1099 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1100 (unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
1102 "flag_unsafe_math_optimizations"
1103 "%.\\tex2.approx%t0\\t%0, %1;")
1105 ;; Conversions involving floating point
1107 (define_insn "extendsfdf2"
1108 [(set (match_operand:DF 0 "nvptx_register_operand" "=R")
1109 (float_extend:DF (match_operand:SF 1 "nvptx_register_operand" "R")))]
1111 "%.\\tcvt%t0%t1\\t%0, %1;")
1113 (define_insn "truncdfsf2"
1114 [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
1115 (float_truncate:SF (match_operand:DF 1 "nvptx_register_operand" "R")))]
1117 "%.\\tcvt%#%t0%t1\\t%0, %1;")
1119 (define_insn "floatunssi<mode>2"
1120 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1121 (unsigned_float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
1123 "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
1125 (define_insn "floatsi<mode>2"
1126 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1127 (float:SDFM (match_operand:SI 1 "nvptx_register_operand" "R")))]
1129 "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
1131 (define_insn "floatunsdi<mode>2"
1132 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1133 (unsigned_float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
1135 "%.\\tcvt%#%t0.u%T1\\t%0, %1;")
1137 (define_insn "floatdi<mode>2"
1138 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1139 (float:SDFM (match_operand:DI 1 "nvptx_register_operand" "R")))]
1141 "%.\\tcvt%#%t0.s%T1\\t%0, %1;")
1143 (define_insn "fixuns_trunc<mode>si2"
1144 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1145 (unsigned_fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1147 "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
1149 (define_insn "fix_trunc<mode>si2"
1150 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1151 (fix:SI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1153 "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
1155 (define_insn "fixuns_trunc<mode>di2"
1156 [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
1157 (unsigned_fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1159 "%.\\tcvt.rzi.u%T0%t1\\t%0, %1;")
1161 (define_insn "fix_trunc<mode>di2"
1162 [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
1163 (fix:DI (match_operand:SDFM 1 "nvptx_register_operand" "R")))]
1165 "%.\\tcvt.rzi.s%T0%t1\\t%0, %1;")
1167 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
1168 UNSPEC_FPINT_CEIL UNSPEC_FPINT_NEARBYINT])
1169 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
1170 (UNSPEC_FPINT_BTRUNC "btrunc")
1171 (UNSPEC_FPINT_CEIL "ceil")
1172 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
1173 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
1174 (UNSPEC_FPINT_BTRUNC ".rzi")
1175 (UNSPEC_FPINT_CEIL ".rpi")
1176 (UNSPEC_FPINT_NEARBYINT "%#i")])
1178 (define_insn "<FPINT:fpint_name><SDFM:mode>2"
1179 [(set (match_operand:SDFM 0 "nvptx_register_operand" "=R")
1180 (unspec:SDFM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
1183 "%.\\tcvt<FPINT:fpint_roundingmode>%t0%t1\\t%0, %1;")
1185 (define_int_iterator FPINT2 [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_CEIL])
1186 (define_int_attr fpint2_name [(UNSPEC_FPINT_FLOOR "lfloor")
1187 (UNSPEC_FPINT_CEIL "lceil")])
1188 (define_int_attr fpint2_roundingmode [(UNSPEC_FPINT_FLOOR ".rmi")
1189 (UNSPEC_FPINT_CEIL ".rpi")])
1191 (define_insn "<FPINT2:fpint2_name><SDFM:mode><SDIM:mode>2"
1192 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1193 (unspec:SDIM [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
1196 "%.\\tcvt<FPINT2:fpint2_roundingmode>.s%T0%t1\\t%0, %1;")
1205 (define_insn "return"
1209 return nvptx_output_return ();
1212 (define_expand "epilogue"
1213 [(clobber (const_int 0))]
1216 emit_jump_insn (gen_return ());
1220 (define_expand "nonlocal_goto"
1221 [(match_operand 0 "" "")
1222 (match_operand 1 "" "")
1223 (match_operand 2 "" "")
1224 (match_operand 3 "" "")]
1227 sorry ("target cannot support nonlocal goto.");
1228 emit_insn (gen_nop ());
1232 (define_expand "nonlocal_goto_receiver"
1236 sorry ("target cannot support nonlocal goto.");
1239 (define_expand "allocate_stack"
1240 [(match_operand 0 "nvptx_register_operand")
1241 (match_operand 1 "nvptx_register_operand")]
1244 /* The ptx documentation specifies an alloca intrinsic (for 32 bit
1245 only) but notes it is not implemented. The assembler emits a
1246 confused error message. Issue a blunt one now instead. */
1247 sorry ("target cannot support alloca.");
1248 emit_insn (gen_nop ());
1251 emit_insn (gen_allocate_stack_di (operands[0], operands[1]));
1253 emit_insn (gen_allocate_stack_si (operands[0], operands[1]));
1257 (define_insn "allocate_stack_<mode>"
1258 [(set (match_operand:P 0 "nvptx_register_operand" "=R")
1259 (unspec:P [(match_operand:P 1 "nvptx_register_operand" "R")]
1262 "%.\\tcall (%0), %%alloca, (%1);")
1264 (define_expand "restore_stack_block"
1265 [(match_operand 0 "register_operand" "")
1266 (match_operand 1 "register_operand" "")]
1272 (define_expand "restore_stack_function"
1273 [(match_operand 0 "register_operand" "")
1274 (match_operand 1 "register_operand" "")]
1281 [(trap_if (const_int 1) (const_int 0))]
1285 (define_insn "trap_if_true"
1286 [(trap_if (ne (match_operand:BI 0 "nvptx_register_operand" "R")
1292 (define_insn "trap_if_false"
1293 [(trap_if (eq (match_operand:BI 0 "nvptx_register_operand" "R")
1299 (define_expand "ctrap<mode>4"
1300 [(trap_if (match_operator 0 "nvptx_comparison_operator"
1301 [(match_operand:SDIM 1 "nvptx_register_operand")
1302 (match_operand:SDIM 2 "nvptx_nonmemory_operand")])
1303 (match_operand 3 "const_0_operand"))]
1306 rtx t = nvptx_expand_compare (operands[0]);
1307 emit_insn (gen_trap_if_true (t));
1311 (define_insn "*oacc_ntid_insn"
1312 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1313 (unspec:SI [(match_operand:SI 1 "const_int_operand" "n")] UNSPEC_NTID))]
1315 "%.\\tmov.u32 %0, %%ntid%d1;")
1317 (define_expand "oacc_ntid"
1318 [(set (match_operand:SI 0 "nvptx_register_operand" "")
1319 (unspec:SI [(match_operand:SI 1 "const_int_operand" "")] UNSPEC_NTID))]
1322 if (INTVAL (operands[1]) < 0 || INTVAL (operands[1]) > 2)
1326 (define_insn "*oacc_tid_insn"
1327 [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
1328 (unspec:SI [(match_operand:SI 1 "const_int_operand" "n")] UNSPEC_TID))]
1330 "%.\\tmov.u32 %0, %%tid%d1;")
1332 (define_expand "oacc_tid"
1333 [(set (match_operand:SI 0 "nvptx_register_operand" "")
1334 (unspec:SI [(match_operand:SI 1 "const_int_operand" "")] UNSPEC_TID))]
1337 if (INTVAL (operands[1]) < 0 || INTVAL (operands[1]) > 2)
1343 (define_expand "atomic_compare_and_swap<mode>"
1344 [(match_operand:SI 0 "nvptx_register_operand") ;; bool success output
1345 (match_operand:SDIM 1 "nvptx_register_operand") ;; oldval output
1346 (match_operand:SDIM 2 "memory_operand") ;; memory
1347 (match_operand:SDIM 3 "nvptx_register_operand") ;; expected input
1348 (match_operand:SDIM 4 "nvptx_register_operand") ;; newval input
1349 (match_operand:SI 5 "const_int_operand") ;; is_weak
1350 (match_operand:SI 6 "const_int_operand") ;; success model
1351 (match_operand:SI 7 "const_int_operand")] ;; failure model
1354 emit_insn (gen_atomic_compare_and_swap<mode>_1
1355 (operands[1], operands[2], operands[3], operands[4], operands[6]));
1357 rtx cond = gen_reg_rtx (BImode);
1358 emit_move_insn (cond, gen_rtx_EQ (BImode, operands[1], operands[3]));
1359 emit_insn (gen_sel_truesi (operands[0], cond, GEN_INT (1), GEN_INT (0)));
1363 (define_insn "atomic_compare_and_swap<mode>_1"
1364 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1365 (unspec_volatile:SDIM
1366 [(match_operand:SDIM 1 "memory_operand" "+m")
1367 (match_operand:SDIM 2 "nvptx_register_operand" "R")
1368 (match_operand:SDIM 3 "nvptx_register_operand" "R")
1369 (match_operand:SI 4 "const_int_operand")]
1372 (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
1374 "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;")
1376 (define_insn "atomic_exchange<mode>"
1377 [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R") ;; output
1378 (unspec_volatile:SDIM
1379 [(match_operand:SDIM 1 "memory_operand" "+m") ;; memory
1380 (match_operand:SI 3 "const_int_operand")] ;; model
1383 (match_operand:SDIM 2 "nvptx_register_operand" "R"))] ;; input
1385 "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;")
1387 (define_insn "atomic_fetch_add<mode>"
1388 [(set (match_operand:SDIM 1 "memory_operand" "+m")
1389 (unspec_volatile:SDIM
1390 [(plus:SDIM (match_dup 1)
1391 (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1392 (match_operand:SI 3 "const_int_operand")] ;; model
1394 (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1397 "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1399 (define_insn "atomic_fetch_addsf"
1400 [(set (match_operand:SF 1 "memory_operand" "+m")
1402 [(plus:SF (match_dup 1)
1403 (match_operand:SF 2 "nvptx_nonmemory_operand" "RF"))
1404 (match_operand:SI 3 "const_int_operand")] ;; model
1406 (set (match_operand:SF 0 "nvptx_register_operand" "=R")
1409 "%.\\tatom%A1.add%t0\\t%0, %1, %2;")
1411 (define_code_iterator any_logic [and ior xor])
1412 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1414 ;; Currently disabled until we add better subtarget support - requires sm_32.
1415 (define_insn "atomic_fetch_<logic><mode>"
1416 [(set (match_operand:SDIM 1 "memory_operand" "+m")
1417 (unspec_volatile:SDIM
1418 [(any_logic:SDIM (match_dup 1)
1419 (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))
1420 (match_operand:SI 3 "const_int_operand")] ;; model
1422 (set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
1425 "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;")