diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
index ce74672..a36ea59 100644
--- a/gcc/config/nvptx/nvptx.md
+++ b/gcc/config/nvptx/nvptx.md
@@ -27,6 +27,7 @@
    UNSPEC_SIN
    UNSPEC_COS
    UNSPEC_TANH
+   UNSPEC_ISINF
 
    UNSPEC_FPINT_FLOOR
    UNSPEC_FPINT_BTRUNC
@@ -592,6 +593,12 @@
   ""
   "%.\\tnot.b%T0\\t%0, %1;")
 
+(define_insn "one_cmplbi2"
+  [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
+	(not:BI (match_operand:BI 1 "nvptx_register_operand" "R")))]
+  ""
+  "%.\\tnot.pred\\t%0, %1;")
+
 (define_insn "*cnot<mode>2"
   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
 	(eq:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
@@ -667,7 +674,57 @@
   ""
   "%.\\tmul.wide.u32\\t%0, %1, %2;")
 
-(define_insn "smulhi3_highpart"
+(define_expand "mulditi3"
+  [(set (match_operand:TI 0 "nvptx_register_operand")
+	(mult:TI (sign_extend:TI
+		  (match_operand:DI 1 "nvptx_register_operand"))
+		 (sign_extend:DI
+		  (match_operand:DI 2 "nvptx_nonmemory_operand"))))]
+  ""
+{
+  rtx hi = gen_reg_rtx (DImode);
+  rtx lo = gen_reg_rtx (DImode);
+  emit_insn (gen_smuldi3_highpart (hi, operands[1], operands[2]));
+  emit_insn (gen_muldi3 (lo, operands[1], operands[2]));
+  emit_move_insn (gen_highpart (DImode, operands[0]), hi);
+  emit_move_insn (gen_lowpart (DImode, operands[0]), lo);
+  DONE;
+})
+
+(define_expand "umulditi3"
+  [(set (match_operand:TI 0 "nvptx_register_operand")
+	(mult:TI (zero_extend:TI
+		  (match_operand:DI 1 "nvptx_register_operand"))
+		 (zero_extend:DI
+		  (match_operand:DI 2 "nvptx_nonmemory_operand"))))]
+  ""
+{
+  rtx hi = gen_reg_rtx (DImode);
+  rtx lo = gen_reg_rtx (DImode);
+  emit_insn (gen_umuldi3_highpart (hi, operands[1], operands[2]));
+  emit_insn (gen_muldi3 (lo, operands[1], operands[2]));
+  emit_move_insn (gen_highpart (DImode, operands[0]), hi);
+  emit_move_insn (gen_lowpart (DImode, operands[0]), lo);
+  DONE;
+})
+
+(define_insn "smul<mode>3_highpart"
+  [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
+	(smul_highpart:HSDIM
+	  (match_operand:HSDIM 1 "nvptx_register_operand" "R")
+	  (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
+  ""
+  "%.\\tmul.hi.s%T0\\t%0, %1, %2;")
+
+(define_insn "umul<mode>3_highpart"
+  [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
+	(umul_highpart:HSDIM
+	  (match_operand:HSDIM 1 "nvptx_register_operand" "R")
+	  (match_operand:HSDIM 2 "nvptx_nonmemory_operand" "Ri")))]
+  ""
+  "%.\\tmul.hi.u%T0\\t%0, %1, %2;")
+
+(define_insn "*smulhi3_highpart_2"
   [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
 	(truncate:HI
 	 (lshiftrt:SI
@@ -679,7 +736,7 @@
   ""
   "%.\\tmul.hi.s16\\t%0, %1, %2;")
 
-(define_insn "smulsi3_highpart"
+(define_insn "*smulsi3_highpart_2"
   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
 	(truncate:SI
 	 (lshiftrt:DI
@@ -691,7 +748,7 @@
   ""
   "%.\\tmul.hi.s32\\t%0, %1, %2;")
 
-(define_insn "umulhi3_highpart"
+(define_insn "*umulhi3_highpart_2"
   [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
 	(truncate:HI
 	 (lshiftrt:SI
@@ -703,7 +760,7 @@
   ""
   "%.\\tmul.hi.u16\\t%0, %1, %2;")
 
-(define_insn "umulsi3_highpart"
+(define_insn "*umulsi3_highpart_2"
   [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
 	(truncate:SI
 	 (lshiftrt:DI
@@ -873,6 +930,13 @@
   ""
   "%.\\tselp%t0\\t%0, 1, 0, %1;")
 
+(define_insn "*setcc<mode>_from_not_bi"
+  [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
+	(eq:HSDIM (match_operand:BI 1 "nvptx_register_operand" "R")
+		   (const_int 0)))]
+  ""
+  "%.\\tselp%t0\\t%0, 0, 1, %1;")
+
 (define_insn "extendbi<mode>2"
   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
 	(sign_extend:HSDIM
@@ -1133,6 +1197,25 @@
   "flag_unsafe_math_optimizations"
   "%.\\tex2.approx%t0\\t%0, %1;")
 
+(define_insn "setcc_isinf<mode>"
+  [(set (match_operand:BI 0 "nvptx_register_operand" "=R")
+	(unspec:BI [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
+		   UNSPEC_ISINF))]
+  ""
+  "%.\\ttestp.infinite%t1\\t%0, %1;")
+
+(define_expand "isinf<mode>2"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+	(unspec:SI [(match_operand:SDFM 1 "nvptx_register_operand" "R")]
+		   UNSPEC_ISINF))]
+  ""
+{
+  rtx pred = gen_reg_rtx (BImode);
+  emit_insn (gen_setcc_isinf<mode> (pred, operands[1]));
+  emit_insn (gen_setccsi_from_bi (operands[0], pred));
+  DONE;
+})
+
 ;; HFmode floating point arithmetic.
 
 (define_insn "addhf3"
diff --git a/gcc/testsuite/gcc.target/nvptx/isinf.c b/gcc/testsuite/gcc.target/nvptx/isinf.c
new file mode 100644
index 0000000..c433612
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/isinf.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int foo(double x)
+{
+  return __builtin_isinf(x);
+}
+
+/* { dg-final { scan-assembler-times "testp.infinite.f64" 1 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/mul-hi64.c b/gcc/testsuite/gcc.target/nvptx/mul-hi64.c
new file mode 100644
index 0000000..a45a0e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/mul-hi64.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-long-long" } */
+
+typedef unsigned int __attribute ((mode(TI))) uti_t;
+typedef int __attribute ((mode(TI))) ti_t;
+
+long test1(long x, long y)
+{
+  return ((ti_t)x * (ti_t)y) >> 64;
+}
+
+long test2(long x)
+{
+  return ((ti_t)x * 19065) >> 64;
+}
+
+long test3(long x, long y)
+{
+  return (uti_t)((ti_t)x * (ti_t)y) >> 64;
+}
+
+long test4(long x)
+{
+  return (uti_t)((ti_t)x * 19065) >> 64;
+}
+
+ti_t test5(long x, long y)
+{
+  return ((ti_t)x * (ti_t)y) >> 64;
+}
+
+ti_t test6(long x)
+{
+  return ((ti_t)x * 19065) >> 64;
+}
+
+uti_t test7(long x, long y)
+{
+  return (uti_t)((ti_t)x * (ti_t)y) >> 64;
+}
+
+uti_t test8(long x)
+{
+  return (uti_t)((ti_t)x * 19065) >> 64;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.s64" 8 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/mul-wide64.c b/gcc/testsuite/gcc.target/nvptx/mul-wide64.c
new file mode 100644
index 0000000..a273c66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/mul-wide64.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int __attribute ((mode(TI))) ti_t;
+
+ti_t foo(long x, long y)
+{
+  return (ti_t)x * (ti_t)y;
+}
+
+/* { dg-final { scan-assembler-times "mul.lo.u64" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.s64" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/nvptx/umul-hi64.c b/gcc/testsuite/gcc.target/nvptx/umul-hi64.c
new file mode 100644
index 0000000..6e09b74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/umul-hi64.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-long-long" } */
+
+typedef unsigned int __attribute ((mode(TI))) uti_t;
+typedef int __attribute ((mode(TI))) ti_t;
+
+unsigned long test1(unsigned long x, unsigned long y)
+{
+  return ((uti_t)x * (uti_t)y) >> 64;
+}
+
+unsigned long test2(unsigned long x)
+{
+  return ((uti_t)x * 19065) >> 64;
+}
+
+unsigned long test3(unsigned long x, unsigned long y)
+{
+  return (ti_t)((uti_t)x * (uti_t)y) >> 64;
+}
+
+unsigned long test4(unsigned long x)
+{
+  return (ti_t)((uti_t)x * 19065) >> 64;
+}
+
+uti_t test5(unsigned long x, unsigned long y)
+{
+  return ((uti_t)x * (uti_t)y) >> 64;
+}
+
+uti_t test6(unsigned long x)
+{
+  return ((uti_t)x * 19065) >> 64;
+}
+
+ti_t test7(unsigned long x, unsigned long y)
+{
+  return (ti_t)((uti_t)x * (uti_t)y) >> 64;
+}
+
+ti_t test8(unsigned long x)
+{
+  return (ti_t)((uti_t)x * 19065) >> 64;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.u64" 8 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/umul-wide64.c b/gcc/testsuite/gcc.target/nvptx/umul-wide64.c
new file mode 100644
index 0000000..4cbdf0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/umul-wide64.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int __attribute ((mode(TI))) uti_t;
+
+uti_t foo(unsigned long x, unsigned long y)
+{
+  return (uti_t)x * (uti_t)y;
+}
+
+/* { dg-final { scan-assembler-times "mul.lo.u64" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.u64" 1 } } */
+
