diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 0c5b264..6f68257 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -429,9 +429,11 @@ LIB2ADD += enable-execute-stack.c
 # While emutls.c has nothing to do with EH, it is in LIB2ADDEH*
 # instead of LIB2ADD because that's the way to be sure on some targets
 # (e.g. *-*-darwin*) only one copy of it is linked.
+ifneq ($(enable_emutls),no)
 LIB2ADDEH += $(srcdir)/emutls.c
 LIB2ADDEHSTATIC += $(srcdir)/emutls.c
 LIB2ADDEHSHARED += $(srcdir)/emutls.c
+endif
 
 # Library members defined in libgcc2.c.
 lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
diff --git a/libgcc/config.host b/libgcc/config.host
index 029f656..29178da 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -91,6 +91,10 @@ alpha*-*-*)
 am33_2.0-*-linux*)
 	cpu_type=mn10300
 	;;
+amdgcn*-*-*)
+	cpu_type=gcn
+	tmake_file="${tmake_file} t-softfp-sfdf t-softfp"
+	;;
 arc*-*-*)
 	cpu_type=arc
 	;;
@@ -384,6 +388,10 @@ alpha*-dec-*vms*)
 	extra_parts="$extra_parts vms-dwarf2.o vms-dwarf2eh.o"
 	md_unwind_header=alpha/vms-unwind.h
 	;;
+amdgcn*-*-amdhsa)
+	tmake_file="$tmake_file gcn/t-amdgcn"
+	extra_parts="crt0.o"
+	;;
 arc*-*-elf*)
 	tmake_file="arc/t-arc"
 	extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o"
diff --git a/libgcc/config/gcn/crt0.c b/libgcc/config/gcn/crt0.c
new file mode 100644
index 0000000..f4f367b
--- /dev/null
+++ b/libgcc/config/gcn/crt0.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This file is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Provide an entry point symbol to silence a linker warning.  */
+void _start() {}
diff --git a/libgcc/config/gcn/gomp_print.c b/libgcc/config/gcn/gomp_print.c
new file mode 100644
index 0000000..41f50c3
--- /dev/null
+++ b/libgcc/config/gcn/gomp_print.c
@@ -0,0 +1,99 @@
+/* Newlib may not have been built yet.  */
+typedef long int64_t;
+typedef long size_t;
+extern char *strncpy (char *dst, const char *src, size_t length);
+extern void exit(int);
+
+void gomp_print_string (const char *msg, const char *value);
+void gomp_print_integer (const char *msg, int64_t value);
+void gomp_print_double (const char *msg, double value);
+
+/* This struct must match the one used by gcn-run and libgomp.
+   It holds all the data output from a kernel (besides mapping data).
+ 
+   The base address pointer can be found at kernargs+16.
+ 
+   The next_output counter must be atomically incremented for each
+   print output.  Only when the print data is fully written can the
+   "written" flag be set.  */
+struct output {
+  int return_value;
+  int next_output;
+  struct printf_data {
+    int written;
+    char msg[128];
+    int type;
+    union {
+      int64_t ivalue;
+      double dvalue;
+      char text[128];
+    };
+  } queue[1000];
+};
+
+static struct printf_data *
+reserve_print_slot (void) {
+  /* The kernargs pointer is in s[8:9].
+     This will break if the enable_sgpr_* flags are ever changed.  */
+  char *kernargs;
+  asm ("s_mov_b64 %0, s[8:9]" : "=Sg"(kernargs));
+
+  /* The output data is at kernargs[2].  */
+  struct output *data = *(struct output **)(kernargs + 16);
+
+  /* We don't have atomic operators in C yet.
+     "glc" means return original value.  */
+  int index = 0;
+  asm ("flat_atomic_add %0, %1, %2 glc\n\t"
+       "s_waitcnt 0"
+       : "=v"(index)
+       : "v"(&data->next_output), "v"(1), "e"(1l));
+
+  if (index >= 1000)
+    exit(1);
+
+  return &(data->queue[index]);
+}
+
+void
+gomp_print_string (const char *msg, const char *value)
+{
+  struct printf_data *output = reserve_print_slot ();
+  output->type = 2; /* String.  */
+
+  strncpy (output->msg, msg, 127);
+  output->msg[127] = '\0';
+  strncpy (output->text, value, 127);
+  output->text[127] = '\0';
+
+  asm ("" ::: "memory");
+  output->written = 1;
+}
+
+void
+gomp_print_integer (const char *msg, int64_t value)
+{
+  struct printf_data *output = reserve_print_slot ();
+  output->type = 0; /* Integer.  */
+
+  strncpy (output->msg, msg, 127);
+  output->msg[127] = '\0';
+  output->ivalue = value;
+
+  asm ("" ::: "memory");
+  output->written = 1;
+}
+
+void
+gomp_print_double (const char *msg, double value)
+{
+  struct printf_data *output = reserve_print_slot ();
+  output->type = 1; /* Double.  */
+
+  strncpy (output->msg, msg, 127);
+  output->msg[127] = '\0';
+  output->dvalue = value;
+
+  asm ("" ::: "memory");
+  output->written = 1;
+}
diff --git a/libgcc/config/gcn/lib2-divmod-hi.c b/libgcc/config/gcn/lib2-divmod-hi.c
new file mode 100644
index 0000000..d57e145
--- /dev/null
+++ b/libgcc/config/gcn/lib2-divmod-hi.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   Contributed by Altera and Mentor Graphics, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "lib2-gcn.h"
+
+/* 16-bit HI divide and modulo as used in gcn.  */
+
+static UHItype
+udivmodhi4 (UHItype num, UHItype den, word_type modwanted)
+{
+  UHItype bit = 1;
+  UHItype res = 0;
+
+  while (den < num && bit && !(den & (1L<<15)))
+    {
+      den <<=1;
+      bit <<=1;
+    }
+  while (bit)
+    {
+      if (num >= den)
+	{
+	  num -= den;
+	  res |= bit;
+	}
+      bit >>=1;
+      den >>=1;
+    }
+  if (modwanted)
+    return num;
+  return res;
+}
+
+
+HItype
+__divhi3 (HItype a, HItype b)
+{
+  word_type neg = 0;
+  HItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = !neg;
+    }
+
+  if (b < 0)
+    {
+      b = -b;
+      neg = !neg;
+    }
+
+  res = udivmodhi4 (a, b, 0);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+
+HItype
+__modhi3 (HItype a, HItype b)
+{
+  word_type neg = 0;
+  HItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = 1;
+    }
+
+  if (b < 0)
+    b = -b;
+
+  res = udivmodhi4 (a, b, 1);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+
+UHItype
+__udivhi3 (UHItype a, UHItype b)
+{
+  return udivmodhi4 (a, b, 0);
+}
+
+
+UHItype
+__umodhi3 (UHItype a, UHItype b)
+{
+  return udivmodhi4 (a, b, 1);
+}
+
diff --git a/libgcc/config/gcn/lib2-divmod.c b/libgcc/config/gcn/lib2-divmod.c
new file mode 100644
index 0000000..08e7103
--- /dev/null
+++ b/libgcc/config/gcn/lib2-divmod.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   Contributed by Altera and Mentor Graphics, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "lib2-gcn.h"
+
+/* 32-bit SI divide and modulo as used in gcn.  */
+
+static USItype
+udivmodsi4 (USItype num, USItype den, word_type modwanted)
+{
+  USItype bit = 1;
+  USItype res = 0;
+
+  while (den < num && bit && !(den & (1L<<31)))
+    {
+      den <<=1;
+      bit <<=1;
+    }
+  while (bit)
+    {
+      if (num >= den)
+	{
+	  num -= den;
+	  res |= bit;
+	}
+      bit >>=1;
+      den >>=1;
+    }
+  if (modwanted)
+    return num;
+  return res;
+}
+
+
+SItype
+__divsi3 (SItype a, SItype b)
+{
+  word_type neg = 0;
+  SItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = !neg;
+    }
+
+  if (b < 0)
+    {
+      b = -b;
+      neg = !neg;
+    }
+
+  res = udivmodsi4 (a, b, 0);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+
+SItype
+__modsi3 (SItype a, SItype b)
+{
+  word_type neg = 0;
+  SItype res;
+
+  if (a < 0)
+    {
+      a = -a;
+      neg = 1;
+    }
+
+  if (b < 0)
+    b = -b;
+
+  res = udivmodsi4 (a, b, 1);
+
+  if (neg)
+    res = -res;
+
+  return res;
+}
+
+
+SItype
+__udivsi3 (SItype a, SItype b)
+{
+  return udivmodsi4 (a, b, 0);
+}
+
+
+SItype
+__umodsi3 (SItype a, SItype b)
+{
+  return udivmodsi4 (a, b, 1);
+}
+
diff --git a/libgcc/config/gcn/lib2-gcn.h b/libgcc/config/gcn/lib2-gcn.h
new file mode 100644
index 0000000..aff0bd2
--- /dev/null
+++ b/libgcc/config/gcn/lib2-gcn.h
@@ -0,0 +1,49 @@
+/* Integer arithmetic support for gcn.
+
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   Contributed by Altera and Mentor Graphics, Inc.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This file is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef LIB2_GCN_H
+#define LIB2_GCN_H
+
+/* Types.  */
+
+typedef char QItype __attribute__ ((mode (QI)));
+typedef unsigned char UQItype __attribute__ ((mode (QI)));
+typedef short HItype __attribute__ ((mode (HI)));
+typedef unsigned short UHItype __attribute__ ((mode (HI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+/* Exported functions.  */
+extern SItype __divsi3 (SItype, SItype);
+extern SItype __modsi3 (SItype, SItype);
+extern SItype __udivsi3 (SItype, SItype);
+extern SItype __umodsi3 (SItype, SItype);
+extern HItype __divhi3 (HItype, HItype);
+extern HItype __modhi3 (HItype, HItype);
+extern UHItype __udivhi3 (UHItype, UHItype);
+extern UHItype __umodhi3 (UHItype, UHItype);
+extern SItype __mulsi3 (SItype, SItype);
+
+#endif /* LIB2_GCN_H */
diff --git a/libgcc/config/gcn/reduction.c b/libgcc/config/gcn/reduction.c
new file mode 100644
index 0000000..fbe9aaa
--- /dev/null
+++ b/libgcc/config/gcn/reduction.c
@@ -0,0 +1,30 @@
+/* Oversized reductions lock variable
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   Contributed by Mentor Graphics.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* We use a global lock variable for reductions on objects larger than
+   64 bits.  Until and unless proven that lock contention for
+   different reductions is a problem, a single lock will suffice.  */
+
+unsigned volatile __reduction_lock = 0;
diff --git a/libgcc/config/gcn/sfp-machine.h b/libgcc/config/gcn/sfp-machine.h
new file mode 100644
index 0000000..7874081
--- /dev/null
+++ b/libgcc/config/gcn/sfp-machine.h
@@ -0,0 +1,51 @@
+/* Use 32-bit types here to prevent longlong.h trying to use TImode.
+   Once TImode works we might be better to use 64-bit here.  */
+
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+#define _FP_MUL_MEAT_S(R,X,Y)				\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)				\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_QNANNEGATEDP 0
+
+/* Someone please check this.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    else							\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define _FP_TININESS_AFTER_ROUNDING 0
+
+#define __LITTLE_ENDIAN 1234
+#define	__BIG_ENDIAN	4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
diff --git a/libgcc/config/gcn/t-amdgcn b/libgcc/config/gcn/t-amdgcn
new file mode 100644
index 0000000..d0c423d
--- /dev/null
+++ b/libgcc/config/gcn/t-amdgcn
@@ -0,0 +1,25 @@
+LIB2ADD += $(srcdir)/config/gcn/gomp_print.c
+
+LIB2ADD += $(srcdir)/config/gcn/lib2-divmod.c \
+	   $(srcdir)/config/gcn/lib2-divmod-hi.c
+
+LIB2ADD += $(srcdir)/config/gcn/reduction.c
+
+LIB2ADDEH=
+LIB2FUNCS_EXCLUDE=__main
+
+override LIB2FUNCS_ST := $(filter-out __gcc_bcmp,$(LIB2FUNCS_ST))
+
+# Debug information is not useful, and probably uses broken relocations
+LIBGCC2_DEBUG_CFLAGS = -g0
+
+crt0.o: $(srcdir)/config/gcn/crt0.c
+	$(crt_compile) -c $<
+
+# Prevent building "advanced" stuff (for example, gcov support).  We don't
+# support it, and it may cause the build to fail, because of alloca usage, for
+# example.
+INHIBIT_LIBC_CFLAGS = -Dinhibit_libc
+
+# Disable emutls.c (temporarily?)
+enable_emutls = no
