AMD GCN Port

Message ID f7b43b43-59c0-0dd4-5ff9-1c3a45783f48@codesourcery.com
State New
Headers show
Series
  • AMD GCN Port
Related show

Commit Message

Andrew Stubbs Jan. 10, 2019, 12:35 p.m.
Hi all,

The GCC port to the AMD GCN architecture (used in GPUs) will be 
committed soon (I hope), so here is the Newlib port to go with it.

The patch includes enough to run most of the GCC testsuite, and 
therefore most of what users will need for OpenACC/OpenMP offloading. 
I've omitted the config.sub and the generated files from the patch, but 
I would add those before committing.

Because GCN is a GPU architecture there is no real support for I/O. The 
"gcn-run" stand-alone launcher program, and libgomp offload launcher 
(both included with GCC), feature a shared-memory interface to implement 
input arguments, return code, and stdout, but that's all.

On the other hand, because it's a GPU architecture, we absolutely need 
to handle re-entrancy -- there can be hundreds of hardware threads 
running at once -- so the port uses __DYNAMIC_REENT__ and malloc locks.

The port still needs a lot more stub functions for system calls, if it 
is to support Fortran write, for example, but those can wait for another 
time.

OK to commit once GCC is done? (I will also retest at that time.)

-- 
Andrew Stubbs
Mentor Graphics / CodeSourcery

Comments

Jeff Johnston Jan. 10, 2019, 5:17 p.m. | #1
Hi Andrew,

Just one issue.  You are putting your syscalls into the machine directory.
This is no longer done anymore.
Some older ports had syscalls in the sys directory, but were encouraged to
use libgloss instead to allow the user to
specify syscalls on the link (e.g. linking for a simulator vs board config
A vs board config B).

Arm is a pecularity in that they have their syscalls duplicated in both the
libc/sys and libgloss directories.  There is a configuration
option (--disable-newlib-supplied-syscalls) which is used by them to
disable the newlib syscalls so that a user may use libgloss
to substitute the syscalls for various board set-ups.  It is a bit of a
hack and requires dual maintenance.

I would suggest you look at having your syscalls in libgloss at the start.
If you are certain there will never be a need for linking in different
versions, you can put them in libc/sys with have_crt0="no".

-- Jeff J.



On Thu, Jan 10, 2019 at 7:36 AM Andrew Stubbs <ams@codesourcery.com> wrote:

> Hi all,

>

> The GCC port to the AMD GCN architecture (used in GPUs) will be

> committed soon (I hope), so here is the Newlib port to go with it.

>

> The patch includes enough to run most of the GCC testsuite, and

> therefore most of what users will need for OpenACC/OpenMP offloading.

> I've omitted the config.sub and the generated files from the patch, but

> I would add those before committing.

>

> Because GCN is a GPU architecture there is no real support for I/O. The

> "gcn-run" stand-alone launcher program, and libgomp offload launcher

> (both included with GCC), feature a shared-memory interface to implement

> input arguments, return code, and stdout, but that's all.

>

> On the other hand, because it's a GPU architecture, we absolutely need

> to handle re-entrancy -- there can be hundreds of hardware threads

> running at once -- so the port uses __DYNAMIC_REENT__ and malloc locks.

>

> The port still needs a lot more stub functions for system calls, if it

> is to support Fortran write, for example, but those can wait for another

> time.

>

> OK to commit once GCC is done? (I will also retest at that time.)

>

> --

> Andrew Stubbs

> Mentor Graphics / CodeSourcery

>
Andrew Stubbs Jan. 10, 2019, 5:56 p.m. | #2
On 10/01/2019 17:17, Jeff Johnston wrote:
> I would suggest you look at having your syscalls in libgloss at the 

> start.  If you are certain there will never be a need for linking in 

> different

> versions, you can put them in libc/sys with have_crt0="no".


Is there an existing target you'd suggest as a template for the 
configure and make files? There seems to be a lot of variation going on 
in there.

Thanks

Andrew
Jeff Johnston Jan. 10, 2019, 7:22 p.m. | #3
On Thu, Jan 10, 2019 at 12:56 PM Andrew Stubbs <andrew_stubbs@mentor.com>
wrote:

> On 10/01/2019 17:17, Jeff Johnston wrote:

> > I would suggest you look at having your syscalls in libgloss at the

> > start.  If you are certain there will never be a need for linking in

> > different

> > versions, you can put them in libc/sys with have_crt0="no".

>

> Is there an existing target you'd suggest as a template for the

> configure and make files? There seems to be a lot of variation going on

> in there.

>

>

Try libc/sys/sh as a basis.  You have to replace the creat.c in configure.in
with a file you have.
Don't specify crt0.o in Makefile.am and put in your source files.  Create
an empty sys directory under
you libc/sys/xxxx dir to possibly use in the future to replace sys includes.
Other than that, most of your patch from machine dir goes there.  The
libc/machine/xxxx dir should have anything
you are overriding in shared library (often optimized string routines, but
at minimum, setjmp/longjmp
(see libc/machine/fr30).

-- Jeff J.

Thanks
>

> Andrew

>
Andrew Stubbs Jan. 11, 2019, 12:41 p.m. | #4
On 10/01/2019 19:22, Jeff Johnston wrote:
> Try libc/sys/sh as a basis.  You have to replace the creat.c in 

> configure.in <http://configure.in> with a file you have.

> Don't specify crt0.o in Makefile.am and put in your source files.  

> Create an empty sys directory under

> you libc/sys/xxxx dir to possibly use in the future to replace sys includes.

> Other than that, most of your patch from machine dir goes there.  The 

> libc/machine/xxxx dir should have anything

> you are overriding in shared library (often optimized string routines, 

> but at minimum, setjmp/longjmp

> (see libc/machine/fr30).


How about the attached?

I've moved the syscalls, but left the machine overrides in place, I think.

We don't have an implementation for setjmp/longjmp yet, although we'll 
need to look into that when we build out more C++ support.  The register 
file on this architecture is "up to" ~64kB, depending on the thread 
configuration, and there's no well-defined ABI yet (just what the 
compiler implements), so it's trickier than average.

Once again, I've omitted the autogenerated files from the patch file. 
I've also changed to a commit message more in keeping with the new style.

Andrew
AMD GCN Port

Add support for the AMD GCN GPU architecture.  This is primarily intended for
use with OpenMP and OpenACC offloading.  It can also be used for stand-alone
programs, but this is intended mostly for testing the compiler and is not
expected to be useful in general.

The GPU architecture is highly parallel, and therefore Newlib must be
configured to use dynamic re-entrancy, and thread-safe malloc.

The only I/O available is a via a shared-memory interface provided by libgomp
and the gcn-run tool included with GCC.  At this time this is limited to
stdout, argc/argv, and the return code.

diff --git a/newlib/configure.host b/newlib/configure.host
index 6c49cb7..fa805d6 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -118,6 +118,10 @@ case "${host_cpu}" in
 	machine_dir=aarch64
 	libm_machine_dir=aarch64
 	;;
+  amdgcn*)
+	newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__"
+	machine_dir=amdgcn
+	;;
   arc*)
 	machine_dir=arc
 	;;
@@ -442,6 +446,10 @@ case "${host}" in
   aarch64*-*-*)
 	newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB"
 	;;
+  amdgcn*)
+	sys_dir=amdgcn
+	have_crt0="no"
+	;;
   arm*-*-*)
 	newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB"
 	sys_dir=arm
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index a409752..911eeb5 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -452,6 +452,10 @@
 #define __IEEE_BIG_ENDIAN
 #endif
 
+#ifdef __AMDGCN__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
 #ifdef __CYGWIN__
 #define __OBSOLETE_MATH_DEFAULT 0
 #endif
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index 49b62eb..d746b15 100644
--- a/newlib/libc/include/sys/config.h
+++ b/newlib/libc/include/sys/config.h
@@ -8,6 +8,10 @@
 #define MALLOC_ALIGNMENT 16
 #endif
 
+#ifdef __AMDGCN__
+#define __DYNAMIC_REENT__
+#endif
+
 /* exceptions first */
 #if defined(__H8500__) || defined(__W65__)
 #define __SMALL_BITFIELDS
diff --git a/newlib/libc/machine/amdgcn/Makefile.am b/newlib/libc/machine/amdgcn/Makefile.am
new file mode 100644
index 0000000..4d8d2d1
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/Makefile.am
@@ -0,0 +1,15 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = abort.c exit.c atexit.c malloc_support.c getreent.c
+lib_a_CFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/machine/amdgcn/abort.c b/newlib/libc/machine/amdgcn/abort.c
new file mode 100644
index 0000000..ccbca72
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/abort.c
@@ -0,0 +1,25 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <signal.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+abort (void)
+{
+  write (2, "GCN Kernel Aborted\n", 19);
+  exit_with_status_and_signal (0, SIGABRT);
+}
diff --git a/newlib/libc/machine/amdgcn/atexit.c b/newlib/libc/machine/amdgcn/atexit.c
new file mode 100644
index 0000000..6745714
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/atexit.c
@@ -0,0 +1,25 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+
+int
+atexit (void (*function)(void))
+{
+  /* Our current implementation of exit does not run functions registered with
+     atexit, so fail here.  */
+  abort ();
+  return 1;
+}
diff --git a/newlib/libc/machine/amdgcn/configure.in b/newlib/libc/machine/amdgcn/configure.in
new file mode 100644
index 0000000..028e9d7
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/configure.in
@@ -0,0 +1,14 @@
+dnl This is the newlib/libc/machine/amdgcn configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([Makefile.am])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. 
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/machine/amdgcn/exit-value.h b/newlib/libc/machine/amdgcn/exit-value.h
new file mode 100644
index 0000000..6e88625
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit-value.h
@@ -0,0 +1,48 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#ifndef _AMDGCN_EXIT_VALUE_H_
+#define _AMDGCN_EXIT_VALUE_H_
+
+static inline void  __attribute__((noreturn))
+exit_with_int (int val)
+{
+  /* Write the exit value to the conventional place.  */
+  int *return_value;
+  asm ("s_load_dwordx2	%0, s[8:9], 16 glc\n\t"
+       "s_waitcnt	0" : "=Sg"(return_value));
+  *return_value = val;
+
+  /* Terminate the current kernel.  */
+  asm ("s_dcache_wb");
+  asm ("s_endpgm");
+  __builtin_unreachable ();
+}
+
+static inline void  __attribute__((noreturn))
+exit_with_status_and_signal (int val, int signal)
+{
+  if (signal == 0)
+    val = val & 0xff;
+  else
+    {
+      val = (128 + signal) & 0xff;
+      signal = signal & 0xff;
+    }
+
+  exit_with_int ((0xffff << 16) | (signal << 8) | val);
+}
+
+#endif
diff --git a/newlib/libc/machine/amdgcn/exit.c b/newlib/libc/machine/amdgcn/exit.c
new file mode 100644
index 0000000..bdd532e
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+exit (int val)
+{
+  exit_with_status_and_signal (val, 0);
+}
diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c
new file mode 100644
index 0000000..acf10a9
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/getreent.c
@@ -0,0 +1,79 @@
+/* get thread-specific reentrant pointer */
+
+#include <reent.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Copied from the HSA documentation.  */
+typedef struct hsa_signal_s {
+  uint64_t handle;
+} hsa_signal_t;
+typedef struct hsa_kernel_dispatch_packet_s {
+  uint16_t header ;
+  uint16_t setup;
+  uint16_t workgroup_size_x ;
+  uint16_t workgroup_size_y ;
+  uint16_t workgroup_size_z;
+  uint16_t reserved0;
+  uint32_t grid_size_x ;
+  uint32_t grid_size_y ;
+  uint32_t grid_size_z;
+  uint32_t private_segment_size;
+  uint32_t group_segment_size;
+  uint64_t kernel_object;
+  uint64_t reserved2;
+  hsa_signal_t completion_signal;
+} hsa_kernel_dispatch_packet_t;
+
+struct _reent *
+__getreent (void)
+{
+  /* Place the reent data at the top of the stack allocation.
+     s[0:1] contains a 48-bit private segment base address.
+     s11 contains the offset to the base of the stack.
+     s[4:5] contains the dispatch pointer.
+     
+     WARNING: this code will break if s[0:3] is ever used for anything!  */
+  const register long buffer_descriptor asm("s0");
+  long private_segment = buffer_descriptor & 0x0000ffffffffffff;
+  const register int stack_offset asm("s11");
+  const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4");
+
+  struct data {
+    int marker;
+    struct _reent reent;
+  } *data;
+
+  long stack_base = private_segment + stack_offset;
+  long stack_end = stack_base + dispatch_ptr->private_segment_size * 64;
+  long addr = (stack_end - sizeof(struct data)) & ~7;
+  data = (struct data *)addr;
+
+  register long sp asm("s16");
+  if (sp >= addr)
+    goto stackoverflow;
+
+  /* Place a marker in s3 to indicate that the reent data is initialized.
+     The register is known to hold part of an unused buffer descriptor
+     when the kernel is launched.  This may not be unused forever, but
+     we already used s0 and s1 above, so this doesn't do extra harm.  */
+  register int s3 asm("s3");
+  if (s3 != 123456)
+    {
+      asm("s_mov_b32 s3, 123456");
+      data->marker = 123456;
+
+      __builtin_memset (&data->reent, 0, sizeof(struct _reent));
+      _REENT_INIT_PTR_ZEROED (&data->reent);
+    }
+  else if (data->marker != 123456)
+    goto stackoverflow;
+
+
+  return &data->reent;
+
+stackoverflow:
+    write (2, "GCN Stack Overflow!\n", 20);
+    abort ();
+}
+
diff --git a/newlib/libc/machine/amdgcn/malloc_support.c b/newlib/libc/machine/amdgcn/malloc_support.c
new file mode 100644
index 0000000..4848c97
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/malloc_support.c
@@ -0,0 +1,111 @@
+/*
+ * Support file for AMDGCN in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <reent.h>
+
+/* _sbrk_r expects us to use the real errno, not the reentrant one.  */
+#include <errno.h>
+#undef errno
+extern int errno;
+
+/* The runtime passes in heap space like this.  */
+struct heap {
+  int64_t size;
+  char data[0];
+};
+
+static char *__heap_ptr = (char*)-1;
+static char *__heap_end = (char*)-1;
+static int __heap_lock = 0;
+static void *__heap_lock_id = NULL;
+static int __heap_lock_cnt = 0;
+
+void *
+sbrk (ptrdiff_t nbytes)
+{
+  if (__heap_ptr == (char *)-1)
+    {
+      /* Find the heap from kernargs.
+         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 heap data is at kernargs[3].  */
+      struct heap *heap = *(struct heap **)(kernargs + 24);
+
+      __heap_ptr = heap->data;
+      __heap_end = __heap_ptr + heap->size;
+    }
+
+  if ((__heap_ptr + nbytes) >= __heap_end)
+    {
+      errno = ENOMEM;
+      return (void*)-1;
+    }
+
+  char *base = __heap_ptr;
+  __heap_ptr += nbytes;
+
+  return base;
+}
+
+void
+__malloc_lock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id == __heap_lock_id)
+    {
+      if (__heap_lock_cnt < 1)
+	abort ();
+      ++__heap_lock_cnt;
+      return;
+    }
+
+  while (__sync_lock_test_and_set (&__heap_lock, 1))
+    /* A sleep seems like it should allow the wavefront to yeild (maybe?)
+       Use the shortest possible sleep time of 1*64 cycles.  */
+    asm volatile ("s_sleep\t1" ::: "memory");
+
+  if (__heap_lock_id != NULL)
+    abort ();
+  if (__heap_lock_cnt != 0)
+    abort ();
+
+  __heap_lock_cnt = 1;
+  __heap_lock_id = id;
+}
+
+void
+__malloc_unlock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id != __heap_lock_id)
+    abort ();
+  if (__heap_lock_cnt < 1)
+    abort ();
+
+  --__heap_lock_cnt;
+
+  if (__heap_lock_cnt > 0)
+    return;
+
+  __heap_lock_id = NULL;
+  __sync_lock_release (&__heap_lock);
+}
diff --git a/newlib/libc/machine/configure.in b/newlib/libc/machine/configure.in
index 8ebe68b..0d4068c 100644
--- a/newlib/libc/machine/configure.in
+++ b/newlib/libc/machine/configure.in
@@ -25,6 +25,7 @@ if test -n "${machine_dir}"; then
   case ${machine_dir} in
 	a29k) AC_CONFIG_SUBDIRS(a29k) ;;
 	aarch64) AC_CONFIG_SUBDIRS(aarch64) ;;
+	amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;;
 	arc) AC_CONFIG_SUBDIRS(arc) ;;
 	arm) AC_CONFIG_SUBDIRS(arm) ;;
 	bfin) AC_CONFIG_SUBDIRS(bfin) ;;
diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c
index ee014b6..cd51543 100644
--- a/newlib/libc/ssp/stack_protector.c
+++ b/newlib/libc/ssp/stack_protector.c
@@ -5,6 +5,11 @@
 #include <string.h>
 #include <unistd.h>
 
+#if defined(__AMDGCN__)
+/* GCN does not support constructors, yet.  */
+uintptr_t __stack_chk_guard = 0x00000aff; /* 0, 0, '\n', 255  */
+
+#else
 uintptr_t __stack_chk_guard = 0;
 
 void
@@ -24,6 +29,7 @@ __stack_chk_init (void)
   ((unsigned char *)&__stack_chk_guard)[3] = 255;
 #endif
 }
+#endif
 
 void
 __attribute__((__noreturn__))
diff --git a/newlib/libc/sys/amdgcn/Makefile.am b/newlib/libc/sys/amdgcn/Makefile.am
new file mode 100644
index 0000000..1716776
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES) $(CFLAGS)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c
+lib_a_CCASFLAGS = $(AM_CCASFLAGS)
+lib_a_CFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/sys/amdgcn/close.c b/newlib/libc/sys/amdgcn/close.c
new file mode 100644
index 0000000..5bce557
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/close.c
@@ -0,0 +1,24 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int close(int fildes)
+{
+  errno = EIO;
+  return -1;
+}
+
diff --git a/newlib/libc/sys/amdgcn/configure.in b/newlib/libc/sys/amdgcn/configure.in
new file mode 100644
index 0000000..74edb0a
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/configure.in
@@ -0,0 +1,14 @@
+dnl This is the newlib/libc/sys/amdgcn configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([close.c])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. 
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/sys/amdgcn/fstat.c b/newlib/libc/sys/amdgcn/fstat.c
new file mode 100644
index 0000000..b787158
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/fstat.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int fstat(int fildes, struct stat *buf)
+{
+  errno = EIO;
+  return -1;
+}
diff --git a/newlib/libc/sys/amdgcn/isatty.c b/newlib/libc/sys/amdgcn/isatty.c
new file mode 100644
index 0000000..4268f2c
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/isatty.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int isatty(int fd)
+{
+  errno = EINVAL;
+  return 0;
+}
diff --git a/newlib/libc/sys/amdgcn/lseek.c b/newlib/libc/sys/amdgcn/lseek.c
new file mode 100644
index 0000000..be3220b
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/lseek.c
@@ -0,0 +1,24 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+off_t lseek(int fildes, off_t offset, int whence)
+{
+  errno = ESPIPE;
+  return -1;
+}
+
diff --git a/newlib/libc/sys/amdgcn/read.c b/newlib/libc/sys/amdgcn/read.c
new file mode 100644
index 0000000..97385e9
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/read.c
@@ -0,0 +1,21 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdio.h>
+
+_READ_WRITE_RETURN_TYPE read (int fildes, void *buf, size_t nbyte)
+{
+  return 0;
+}
diff --git a/newlib/libc/sys/amdgcn/write.c b/newlib/libc/sys/amdgcn/write.c
new file mode 100644
index 0000000..ce5bd36
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/write.c
@@ -0,0 +1,88 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014, 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+/* 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];
+};
+
+_READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count)
+{
+  if (fd != 1 && fd != 2)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* The output data is at ((void*)kernargs)[2].  */
+  register void **kernargs asm("s8");
+  struct output *data = (struct output *)kernargs[2];
+
+  /* Each output slot allows 256 bytes, so reserve as many as we need. */
+  int slot_count = ((count+1)/256)+1;
+  int index = __atomic_fetch_add (&data->next_output, slot_count,
+				  __ATOMIC_ACQUIRE);
+  for (int c = count;
+       c >= 0 && index < 1000;
+       buf += 256, c -= 256, index++)
+    {
+      if (c < 128)
+	{
+	  memcpy (data->queue[index].msg, buf, c);
+	  data->queue[index].msg[c] = '\0';
+	  data->queue[index].text[0] = '\0';
+	}
+      else if (c < 256)
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, c-128);
+	  data->queue[index].text[c-128] = '\0';
+	}
+      else
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, 128);
+	}
+
+      data->queue[index].type = 3; /* Raw.  */
+      __atomic_store_n (&data->queue[index].written, 1, __ATOMIC_RELEASE);
+    }
+
+  return count;
+}
diff --git a/newlib/libc/sys/configure.in b/newlib/libc/sys/configure.in
index bc6cb88..a65d1e7 100644
--- a/newlib/libc/sys/configure.in
+++ b/newlib/libc/sys/configure.in
@@ -23,6 +23,7 @@ fi
 if test -n "${sys_dir}"; then
   case ${sys_dir} in
 	a29khif) AC_CONFIG_SUBDIRS(a29khif) ;;
+	amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;;
 	arm) AC_CONFIG_SUBDIRS(arm) ;;
 	d10v) AC_CONFIG_SUBDIRS(d10v) ;;
 	decstation) AC_CONFIG_SUBDIRS(decstation) ;;
Andrew Stubbs Jan. 15, 2019, 2:38 p.m. | #5
Here's an updated patch that adds a stub implementation for "signal". 
This was requested during GCC patch review but accidentally omitted from 
the original Newlib patch as posted.

Note that the GCC port is now approved, and will be committed once I've 
completed final testing. (The first round of which demonstrated that 
"signal" was missing -- oops!)

As before, I've omitted config.sub and the generated files.

Is this version OK?

Andrew
AMD GCN Port

Add support for the AMD GCN GPU architecture.  This is primarily intended for
use with OpenMP and OpenACC offloading.  It can also be used for stand-alone
programs, but this is intended mostly for testing the compiler and is not
expected to be useful in general.

The GPU architecture is highly parallel, and therefore Newlib must be
configured to use dynamic re-entrancy, and thread-safe malloc.

The only I/O available is a via a shared-memory interface provided by libgomp
and the gcn-run tool included with GCC.  At this time this is limited to
stdout, argc/argv, and the return code.

diff --git a/newlib/configure.host b/newlib/configure.host
index 6c49cb7..fa805d6 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -118,6 +118,10 @@ case "${host_cpu}" in
 	machine_dir=aarch64
 	libm_machine_dir=aarch64
 	;;
+  amdgcn*)
+	newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__"
+	machine_dir=amdgcn
+	;;
   arc*)
 	machine_dir=arc
 	;;
@@ -442,6 +446,10 @@ case "${host}" in
   aarch64*-*-*)
 	newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB"
 	;;
+  amdgcn*)
+	sys_dir=amdgcn
+	have_crt0="no"
+	;;
   arm*-*-*)
 	newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB"
 	sys_dir=arm
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index a409752..911eeb5 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -452,6 +452,10 @@
 #define __IEEE_BIG_ENDIAN
 #endif
 
+#ifdef __AMDGCN__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
 #ifdef __CYGWIN__
 #define __OBSOLETE_MATH_DEFAULT 0
 #endif
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index 49b62eb..d746b15 100644
--- a/newlib/libc/include/sys/config.h
+++ b/newlib/libc/include/sys/config.h
@@ -8,6 +8,10 @@
 #define MALLOC_ALIGNMENT 16
 #endif
 
+#ifdef __AMDGCN__
+#define __DYNAMIC_REENT__
+#endif
+
 /* exceptions first */
 #if defined(__H8500__) || defined(__W65__)
 #define __SMALL_BITFIELDS
diff --git a/newlib/libc/machine/amdgcn/Makefile.am b/newlib/libc/machine/amdgcn/Makefile.am
new file mode 100644
index 0000000..f672115
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/Makefile.am
@@ -0,0 +1,15 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = abort.c exit.c atexit.c malloc_support.c getreent.c signal.c
+lib_a_CFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/machine/amdgcn/abort.c b/newlib/libc/machine/amdgcn/abort.c
new file mode 100644
index 0000000..ccbca72
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/abort.c
@@ -0,0 +1,25 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <signal.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+abort (void)
+{
+  write (2, "GCN Kernel Aborted\n", 19);
+  exit_with_status_and_signal (0, SIGABRT);
+}
diff --git a/newlib/libc/machine/amdgcn/atexit.c b/newlib/libc/machine/amdgcn/atexit.c
new file mode 100644
index 0000000..6745714
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/atexit.c
@@ -0,0 +1,25 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+
+int
+atexit (void (*function)(void))
+{
+  /* Our current implementation of exit does not run functions registered with
+     atexit, so fail here.  */
+  abort ();
+  return 1;
+}
diff --git a/newlib/libc/machine/amdgcn/configure.in b/newlib/libc/machine/amdgcn/configure.in
new file mode 100644
index 0000000..028e9d7
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/configure.in
@@ -0,0 +1,14 @@
+dnl This is the newlib/libc/machine/amdgcn configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([Makefile.am])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. 
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/machine/amdgcn/exit-value.h b/newlib/libc/machine/amdgcn/exit-value.h
new file mode 100644
index 0000000..6e88625
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit-value.h
@@ -0,0 +1,48 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#ifndef _AMDGCN_EXIT_VALUE_H_
+#define _AMDGCN_EXIT_VALUE_H_
+
+static inline void  __attribute__((noreturn))
+exit_with_int (int val)
+{
+  /* Write the exit value to the conventional place.  */
+  int *return_value;
+  asm ("s_load_dwordx2	%0, s[8:9], 16 glc\n\t"
+       "s_waitcnt	0" : "=Sg"(return_value));
+  *return_value = val;
+
+  /* Terminate the current kernel.  */
+  asm ("s_dcache_wb");
+  asm ("s_endpgm");
+  __builtin_unreachable ();
+}
+
+static inline void  __attribute__((noreturn))
+exit_with_status_and_signal (int val, int signal)
+{
+  if (signal == 0)
+    val = val & 0xff;
+  else
+    {
+      val = (128 + signal) & 0xff;
+      signal = signal & 0xff;
+    }
+
+  exit_with_int ((0xffff << 16) | (signal << 8) | val);
+}
+
+#endif
diff --git a/newlib/libc/machine/amdgcn/exit.c b/newlib/libc/machine/amdgcn/exit.c
new file mode 100644
index 0000000..bdd532e
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+exit (int val)
+{
+  exit_with_status_and_signal (val, 0);
+}
diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c
new file mode 100644
index 0000000..acf10a9
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/getreent.c
@@ -0,0 +1,79 @@
+/* get thread-specific reentrant pointer */
+
+#include <reent.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Copied from the HSA documentation.  */
+typedef struct hsa_signal_s {
+  uint64_t handle;
+} hsa_signal_t;
+typedef struct hsa_kernel_dispatch_packet_s {
+  uint16_t header ;
+  uint16_t setup;
+  uint16_t workgroup_size_x ;
+  uint16_t workgroup_size_y ;
+  uint16_t workgroup_size_z;
+  uint16_t reserved0;
+  uint32_t grid_size_x ;
+  uint32_t grid_size_y ;
+  uint32_t grid_size_z;
+  uint32_t private_segment_size;
+  uint32_t group_segment_size;
+  uint64_t kernel_object;
+  uint64_t reserved2;
+  hsa_signal_t completion_signal;
+} hsa_kernel_dispatch_packet_t;
+
+struct _reent *
+__getreent (void)
+{
+  /* Place the reent data at the top of the stack allocation.
+     s[0:1] contains a 48-bit private segment base address.
+     s11 contains the offset to the base of the stack.
+     s[4:5] contains the dispatch pointer.
+     
+     WARNING: this code will break if s[0:3] is ever used for anything!  */
+  const register long buffer_descriptor asm("s0");
+  long private_segment = buffer_descriptor & 0x0000ffffffffffff;
+  const register int stack_offset asm("s11");
+  const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4");
+
+  struct data {
+    int marker;
+    struct _reent reent;
+  } *data;
+
+  long stack_base = private_segment + stack_offset;
+  long stack_end = stack_base + dispatch_ptr->private_segment_size * 64;
+  long addr = (stack_end - sizeof(struct data)) & ~7;
+  data = (struct data *)addr;
+
+  register long sp asm("s16");
+  if (sp >= addr)
+    goto stackoverflow;
+
+  /* Place a marker in s3 to indicate that the reent data is initialized.
+     The register is known to hold part of an unused buffer descriptor
+     when the kernel is launched.  This may not be unused forever, but
+     we already used s0 and s1 above, so this doesn't do extra harm.  */
+  register int s3 asm("s3");
+  if (s3 != 123456)
+    {
+      asm("s_mov_b32 s3, 123456");
+      data->marker = 123456;
+
+      __builtin_memset (&data->reent, 0, sizeof(struct _reent));
+      _REENT_INIT_PTR_ZEROED (&data->reent);
+    }
+  else if (data->marker != 123456)
+    goto stackoverflow;
+
+
+  return &data->reent;
+
+stackoverflow:
+    write (2, "GCN Stack Overflow!\n", 20);
+    abort ();
+}
+
diff --git a/newlib/libc/machine/amdgcn/malloc_support.c b/newlib/libc/machine/amdgcn/malloc_support.c
new file mode 100644
index 0000000..4848c97
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/malloc_support.c
@@ -0,0 +1,111 @@
+/*
+ * Support file for AMDGCN in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <reent.h>
+
+/* _sbrk_r expects us to use the real errno, not the reentrant one.  */
+#include <errno.h>
+#undef errno
+extern int errno;
+
+/* The runtime passes in heap space like this.  */
+struct heap {
+  int64_t size;
+  char data[0];
+};
+
+static char *__heap_ptr = (char*)-1;
+static char *__heap_end = (char*)-1;
+static int __heap_lock = 0;
+static void *__heap_lock_id = NULL;
+static int __heap_lock_cnt = 0;
+
+void *
+sbrk (ptrdiff_t nbytes)
+{
+  if (__heap_ptr == (char *)-1)
+    {
+      /* Find the heap from kernargs.
+         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 heap data is at kernargs[3].  */
+      struct heap *heap = *(struct heap **)(kernargs + 24);
+
+      __heap_ptr = heap->data;
+      __heap_end = __heap_ptr + heap->size;
+    }
+
+  if ((__heap_ptr + nbytes) >= __heap_end)
+    {
+      errno = ENOMEM;
+      return (void*)-1;
+    }
+
+  char *base = __heap_ptr;
+  __heap_ptr += nbytes;
+
+  return base;
+}
+
+void
+__malloc_lock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id == __heap_lock_id)
+    {
+      if (__heap_lock_cnt < 1)
+	abort ();
+      ++__heap_lock_cnt;
+      return;
+    }
+
+  while (__sync_lock_test_and_set (&__heap_lock, 1))
+    /* A sleep seems like it should allow the wavefront to yeild (maybe?)
+       Use the shortest possible sleep time of 1*64 cycles.  */
+    asm volatile ("s_sleep\t1" ::: "memory");
+
+  if (__heap_lock_id != NULL)
+    abort ();
+  if (__heap_lock_cnt != 0)
+    abort ();
+
+  __heap_lock_cnt = 1;
+  __heap_lock_id = id;
+}
+
+void
+__malloc_unlock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id != __heap_lock_id)
+    abort ();
+  if (__heap_lock_cnt < 1)
+    abort ();
+
+  --__heap_lock_cnt;
+
+  if (__heap_lock_cnt > 0)
+    return;
+
+  __heap_lock_id = NULL;
+  __sync_lock_release (&__heap_lock);
+}
diff --git a/newlib/libc/machine/amdgcn/signal.c b/newlib/libc/machine/amdgcn/signal.c
new file mode 100644
index 0000000..033d8e5
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/signal.c
@@ -0,0 +1,10 @@
+#include <signal.h>
+#include <errno.h>
+
+_sig_func_ptr
+signal (int sig,
+	_sig_func_ptr func)
+{
+  errno = EINVAL;
+  return NULL;
+}
diff --git a/newlib/libc/machine/configure.in b/newlib/libc/machine/configure.in
index 8ebe68b..0d4068c 100644
--- a/newlib/libc/machine/configure.in
+++ b/newlib/libc/machine/configure.in
@@ -25,6 +25,7 @@ if test -n "${machine_dir}"; then
   case ${machine_dir} in
 	a29k) AC_CONFIG_SUBDIRS(a29k) ;;
 	aarch64) AC_CONFIG_SUBDIRS(aarch64) ;;
+	amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;;
 	arc) AC_CONFIG_SUBDIRS(arc) ;;
 	arm) AC_CONFIG_SUBDIRS(arm) ;;
 	bfin) AC_CONFIG_SUBDIRS(bfin) ;;
diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c
index ee014b6..cd51543 100644
--- a/newlib/libc/ssp/stack_protector.c
+++ b/newlib/libc/ssp/stack_protector.c
@@ -5,6 +5,11 @@
 #include <string.h>
 #include <unistd.h>
 
+#if defined(__AMDGCN__)
+/* GCN does not support constructors, yet.  */
+uintptr_t __stack_chk_guard = 0x00000aff; /* 0, 0, '\n', 255  */
+
+#else
 uintptr_t __stack_chk_guard = 0;
 
 void
@@ -24,6 +29,7 @@ __stack_chk_init (void)
   ((unsigned char *)&__stack_chk_guard)[3] = 255;
 #endif
 }
+#endif
 
 void
 __attribute__((__noreturn__))
diff --git a/newlib/libc/sys/amdgcn/Makefile.am b/newlib/libc/sys/amdgcn/Makefile.am
new file mode 100644
index 0000000..1716776
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES) $(CFLAGS)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c
+lib_a_CCASFLAGS = $(AM_CCASFLAGS)
+lib_a_CFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/sys/amdgcn/close.c b/newlib/libc/sys/amdgcn/close.c
new file mode 100644
index 0000000..5bce557
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/close.c
@@ -0,0 +1,24 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int close(int fildes)
+{
+  errno = EIO;
+  return -1;
+}
+
diff --git a/newlib/libc/sys/amdgcn/configure.in b/newlib/libc/sys/amdgcn/configure.in
new file mode 100644
index 0000000..74edb0a
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/configure.in
@@ -0,0 +1,14 @@
+dnl This is the newlib/libc/sys/amdgcn configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([close.c])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. 
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/sys/amdgcn/fstat.c b/newlib/libc/sys/amdgcn/fstat.c
new file mode 100644
index 0000000..b787158
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/fstat.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int fstat(int fildes, struct stat *buf)
+{
+  errno = EIO;
+  return -1;
+}
diff --git a/newlib/libc/sys/amdgcn/isatty.c b/newlib/libc/sys/amdgcn/isatty.c
new file mode 100644
index 0000000..4268f2c
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/isatty.c
@@ -0,0 +1,23 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int isatty(int fd)
+{
+  errno = EINVAL;
+  return 0;
+}
diff --git a/newlib/libc/sys/amdgcn/lseek.c b/newlib/libc/sys/amdgcn/lseek.c
new file mode 100644
index 0000000..be3220b
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/lseek.c
@@ -0,0 +1,24 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+off_t lseek(int fildes, off_t offset, int whence)
+{
+  errno = ESPIPE;
+  return -1;
+}
+
diff --git a/newlib/libc/sys/amdgcn/read.c b/newlib/libc/sys/amdgcn/read.c
new file mode 100644
index 0000000..97385e9
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/read.c
@@ -0,0 +1,21 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdio.h>
+
+_READ_WRITE_RETURN_TYPE read (int fildes, void *buf, size_t nbyte)
+{
+  return 0;
+}
diff --git a/newlib/libc/sys/amdgcn/write.c b/newlib/libc/sys/amdgcn/write.c
new file mode 100644
index 0000000..ce5bd36
--- /dev/null
+++ b/newlib/libc/sys/amdgcn/write.c
@@ -0,0 +1,88 @@
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014, 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+/* 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];
+};
+
+_READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count)
+{
+  if (fd != 1 && fd != 2)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* The output data is at ((void*)kernargs)[2].  */
+  register void **kernargs asm("s8");
+  struct output *data = (struct output *)kernargs[2];
+
+  /* Each output slot allows 256 bytes, so reserve as many as we need. */
+  int slot_count = ((count+1)/256)+1;
+  int index = __atomic_fetch_add (&data->next_output, slot_count,
+				  __ATOMIC_ACQUIRE);
+  for (int c = count;
+       c >= 0 && index < 1000;
+       buf += 256, c -= 256, index++)
+    {
+      if (c < 128)
+	{
+	  memcpy (data->queue[index].msg, buf, c);
+	  data->queue[index].msg[c] = '\0';
+	  data->queue[index].text[0] = '\0';
+	}
+      else if (c < 256)
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, c-128);
+	  data->queue[index].text[c-128] = '\0';
+	}
+      else
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, 128);
+	}
+
+      data->queue[index].type = 3; /* Raw.  */
+      __atomic_store_n (&data->queue[index].written, 1, __ATOMIC_RELEASE);
+    }
+
+  return count;
+}
diff --git a/newlib/libc/sys/configure.in b/newlib/libc/sys/configure.in
index bc6cb88..a65d1e7 100644
--- a/newlib/libc/sys/configure.in
+++ b/newlib/libc/sys/configure.in
@@ -23,6 +23,7 @@ fi
 if test -n "${sys_dir}"; then
   case ${sys_dir} in
 	a29khif) AC_CONFIG_SUBDIRS(a29khif) ;;
+	amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;;
 	arm) AC_CONFIG_SUBDIRS(arm) ;;
 	d10v) AC_CONFIG_SUBDIRS(d10v) ;;
 	decstation) AC_CONFIG_SUBDIRS(decstation) ;;
Jeff Johnston Jan. 15, 2019, 5:09 p.m. | #6
Patch checked in sans config.sub which we normally sync with gcc.  When gcc
has the updated
config.sub, post to the list to ask for a sync.  I have added the license
info to COPYING.NEWLIB.

-- Jeff J.

On Tue, Jan 15, 2019 at 9:38 AM Andrew Stubbs <ams@codesourcery.com> wrote:

> Here's an updated patch that adds a stub implementation for "signal".

> This was requested during GCC patch review but accidentally omitted from

> the original Newlib patch as posted.

>

> Note that the GCC port is now approved, and will be committed once I've

> completed final testing. (The first round of which demonstrated that

> "signal" was missing -- oops!)

>

> As before, I've omitted config.sub and the generated files.

>

> Is this version OK?

>

> Andrew

>
Andrew Stubbs Jan. 15, 2019, 5:24 p.m. | #7
On 15/01/2019 17:09, Jeff Johnston wrote:
> Patch checked in sans config.sub which we normally sync with gcc.  When 

> gcc has the updated

> config.sub, post to the list to ask for a sync.  I have added the 

> license info to COPYING.NEWLIB.


Awesome! :-)

The GNU config project was updated a few weeks ago, and GCC has since 
imported that.

I've attached the diff.

Andrew
Copy GCN-supporting config.sub from GCC.


diff --git a/config.sub b/config.sub
index c95acc6..b29f8f1 100755
--- a/config.sub
+++ b/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-07-03'
+timestamp='2018-08-29'
 
 # 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
@@ -89,7 +89,7 @@ while test $# -gt 0 ; do
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -149,29 +149,39 @@ case $1 in
 		esac
 		;;
 	*-*)
-		# Second component is usually, but not always the OS
-		case $field2 in
-			# Prevent following clause from handling this valid os
-			sun*os*)
-				basic_machine=$field1
-				os=$field2
-				;;
-			# Manufacturers
-			dec* | mips* | sequent* | encore* | pc532* | sgi* | sony* \
-			| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
-			| unicom* | ibm* | next | hp | isi* | apollo | altos* \
-			| convergent* | ncr* | news | 32* | 3600* | 3100* | hitachi* \
-			| c[123]* | convex* | sun | crds | omron* | dg | ultra | tti* \
-			| harris | dolphin | highlevel | gould | cbm | ns | masscomp \
-			| apple | axis | knuth | cray | microblaze* \
-			| sim | cisco | oki | wec | wrs | winbond)
-				basic_machine=$field1-$field2
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
 				os=
 				;;
-			*)
-				basic_machine=$field1
-				os=$field2
-				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						os=
+						;;
+					*)
+						basic_machine=$field1
+						os=$field2
+						;;
+				esac
+			;;
 		esac
 		;;
 	*)
@@ -190,6 +200,14 @@ case $1 in
 				basic_machine=m68010-adobe
 				os=scout
 				;;
+			alliant)
+				basic_machine=fx80-alliant
+				os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				os=
+				;;
 			am29k)
 				basic_machine=a29k-none
 				os=bsd
@@ -198,6 +216,10 @@ case $1 in
 				basic_machine=580-amdahl
 				os=sysv
 				;;
+			amiga)
+				basic_machine=m68k-unknown
+				os=
+				;;
 			amigaos | amigados)
 				basic_machine=m68k-unknown
 				os=amigaos
@@ -234,13 +256,41 @@ case $1 in
 				basic_machine=arm-unknown
 				os=cegcc
 				;;
+			convex-c1)
+				basic_machine=c1-convex
+				os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				os=bsd
+				;;
 			cray)
 				basic_machine=j90-cray
 				os=unicos
 				;;
-			craynv)
-				basic_machine=craynv-cray
-				os=unicosmp
+			crds | unos)
+				basic_machine=m68k-crds
+				os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				os=
 				;;
 			delta88)
 				basic_machine=m88k-motorola
@@ -286,6 +336,9 @@ case $1 in
 				basic_machine=m88k-harris
 				os=sysv3
 				;;
+			hp300)
+				basic_machine=m68k-hp
+				;;
 			hp300bsd)
 				basic_machine=m68k-hp
 				os=bsd
@@ -307,7 +360,7 @@ case $1 in
 				os=mach
 				;;
 			vsta)
-				basic_machine=i386-unknown
+				basic_machine=i386-pc
 				os=vsta
 				;;
 			isi68 | isi)
@@ -371,7 +424,7 @@ case $1 in
 				os=sysv4
 				;;
 			netbsd386)
-				basic_machine=i386-unknown
+				basic_machine=i386-pc
 				os=netbsd
 				;;
 			netwinder)
@@ -454,14 +507,26 @@ case $1 in
 				basic_machine=mips-sei
 				os=seiux
 				;;
+			sequent)
+				basic_machine=i386-sequent
+				os=
+				;;
 			sps7)
 				basic_machine=m68k-bull
 				os=sysv2
 				;;
+			st2000)
+				basic_machine=m68k-tandem
+				os=
+				;;
 			stratus)
 				basic_machine=i860-stratus
 				os=sysv4
 				;;
+			sun2)
+				basic_machine=m68000-sun
+				os=
+				;;
 			sun2os3)
 				basic_machine=m68000-sun
 				os=sunos3
@@ -470,6 +535,10 @@ case $1 in
 				basic_machine=m68000-sun
 				os=sunos4
 				;;
+			sun3)
+				basic_machine=m68k-sun
+				os=
+				;;
 			sun3os3)
 				basic_machine=m68k-sun
 				os=sunos3
@@ -478,6 +547,10 @@ case $1 in
 				basic_machine=m68k-sun
 				os=sunos4
 				;;
+			sun4)
+				basic_machine=sparc-sun
+				os=
+				;;
 			sun4os3)
 				basic_machine=sparc-sun
 				os=sunos3
@@ -490,6 +563,10 @@ case $1 in
 				basic_machine=sparc-sun
 				os=solaris2
 				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				os=
+				;;
 			sv1)
 				basic_machine=sv1-cray
 				os=unicos
@@ -562,417 +639,162 @@ case $1 in
 		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper | csky \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nfp \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv | riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
-		;;
-	c54x)
-		basic_machine=tic54x-unknown
-		;;
-	c55x)
-		basic_machine=tic55x-unknown
-		;;
-	c6x)
-		basic_machine=tic6x-unknown
-		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=${os:-none}
-		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
 		;;
-	m9s12z | m68hcs12z | hcs12z | s12z)
-		basic_machine=s12z-unknown
-		os=${os:-none}
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	ms1)
-		basic_machine=mt-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=${os:-none}
+	orion105)
+		cpu=clipper
+		vendor=highlevel
 		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
 		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
 		;;
 
-	# We use `pc' rather than `unknown'
-	# because (1) that's what they normally are, and
-	# (2) the word "unknown" tends to confuse beginning users.
-	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | csky-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nfp-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv-* | riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
 	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
+		cpu=m68000
+		vendor=att
 		;;
 	3b*)
-		basic_machine=we32k-att
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=linux
+		cpu=we32k
+		vendor=att
 		;;
 	bluegene*)
-		basic_machine=powerpc-ibm
+		cpu=powerpc
+		vendor=ibm
 		os=cnk
 		;;
-	c54x-*)
-		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=${os:-unicos}
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=bsd
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=${os:-elf}
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=${os:-elf}
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
 	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
+		cpu=pdp10
+		vendor=dec
 		os=tops10
 		;;
 	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
+		cpu=pdp10
+		vendor=dec
 		os=tops20
 		;;
 	delta | 3300 | motorola-3300 | motorola-delta \
 	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=${os:-bosx}
+		cpu=m68k
+		vendor=motorola
 		;;
 	dpx2*)
-		basic_machine=m68k-bull
+		cpu=m68k
+		vendor=bull
 		os=sysv3
 		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
-		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
 	encore | umax | mmax)
-		basic_machine=ns32k-encore
+		cpu=ns32k
+		vendor=encore
 		;;
 	elxsi)
-		basic_machine=elxsi-elxsi
+		cpu=elxsi
+		vendor=elxsi
 		os=${os:-bsd}
 		;;
 	fx2800)
-		basic_machine=i860-alliant
+		cpu=i860
+		vendor=alliant
 		;;
 	genix)
-		basic_machine=ns32k-ns
+		cpu=ns32k
+		vendor=ns
 		;;
 	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
+		cpu=hppa1.1
+		vendor=hitachi
 		os=hiuxwe2
 		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
 	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
+		cpu=m68000
+		vendor=hp
 		;;
 	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
+		cpu=m68k
+		vendor=hp
 		;;
 	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k78[0-9] | hp78[0-9])
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
 		os=sysv32
 		;;
 	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
 		os=sysv4
 		;;
 	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
 		os=sysv
 		;;
 	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
 		os=solaris2
 		;;
 	j90 | j90-cray)
-		basic_machine=j90-cray
+		cpu=j90
+		vendor=cray
 		os=${os:-unicos}
 		;;
 	iris | iris4d)
-		basic_machine=mips-sgi
+		cpu=mips
+		vendor=sgi
 		case $os in
 		    irix*)
 			;;
@@ -981,38 +803,23 @@ case $basic_machine in
 			;;
 		esac
 		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=linux
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
 	miniframe)
-		basic_machine=m68000-convergent
+		cpu=m68000
+		vendor=convergent
 		;;
 	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
+		cpu=m68k
+		vendor=atari
 		os=mint
 		;;
-	mips3*-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	ms1-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-		;;
 	news-3600 | risc-news)
-		basic_machine=mips-sony
+		cpu=mips
+		vendor=sony
 		os=newsos
 		;;
 	next | m*-next)
-		basic_machine=m68k-next
+		cpu=m68k
+		vendor=next
 		case $os in
 		    nextstep* )
 			;;
@@ -1025,260 +832,438 @@ case $basic_machine in
 		esac
 		;;
 	np1)
-		basic_machine=np1-gould
+		cpu=np1
+		vendor=gould
 		;;
-	neo-tandem)
-		basic_machine=neo-tandem
+	op50n-* | op60c-*)
+		cpu=hppa1.1
+		vendor=oki
+		os=proelf
 		;;
-	nse-tandem)
-		basic_machine=nse-tandem
+	pa-hitachi)
+		cpu=hppa1.1
+		vendor=hitachi
+		os=hiuxwe2
 		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
+	pbd)
+		cpu=sparc
+		vendor=tti
 		;;
-	nsv-tandem)
-		basic_machine=nsv-tandem
+	pbb)
+		cpu=m68k
+		vendor=tti
 		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
+	pc532)
+		cpu=ns32k
+		vendor=pc532
 		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=proelf
+	pn)
+		cpu=pn
+		vendor=gould
 		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
+	power)
+		cpu=power
+		vendor=ibm
 		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=hiuxwe2
+	ps2)
+		cpu=i386
+		vendor=ibm
 		;;
-	parisc-*)
-		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=linux
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
 		;;
-	pbd)
-		basic_machine=sparc-tti
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
 		;;
-	pbb)
-		basic_machine=m68k-tti
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		os=${os:-elf}
 		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		os=vxworks
 		;;
-	pc98)
-		basic_machine=i386-pc
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
 		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
+		;;
+	w65)
+		cpu=w65
+		vendor=wdc
+		;;
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		os=proelf
 		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
+	none)
+		cpu=none
+		vendor=none
 		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+	leon|leon[3-9])
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=`echo "$basic_machine" | sed 's/-.*//'`
 		;;
-	pentium4)
-		basic_machine=i786-pc
+
+	*-*)
+		IFS="-" read -r cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
+	pc98)
+		cpu=i386
+		vendor=pc
 		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	pn)
-		basic_machine=pn-gould
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		os=${os:-unicosmp}
+		;;
+	c90-unknown | c90-cray)
+		vendor=cray
+		os=${os:-unicos}
 		;;
-	power)	basic_machine=power-ibm
+	fx80-unknown)
+		vendor=alliant
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	romp-unknown)
+		vendor=ibm
 		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	mmix-unknown)
+		vendor=knuth
 		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
+	vax-unknown)
+		vendor=dec
 		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	pdp11-unknown)
+		vendor=dec
 		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
+	we32k-unknown)
+		vendor=att
 		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	ps2)
-		basic_machine=i386-ibm
+	i370-ibm*)
+		vendor=ibm
 		;;
-	rm[46]00)
-		basic_machine=mips-siemens
+	orion-unknown)
+		vendor=highlevel
 		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
+		;;
+
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		os=${os:-bosx}
 		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
+	blackfin-*)
+		cpu=bfin
+		os=linux
 		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
+	c54x-*)
+		cpu=tic54x
 		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
+	c55x-*)
+		cpu=tic55x
 		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=${os:-elf}
+	c6x-*)
+		cpu=tic6x
 		;;
-	sequent)
-		basic_machine=i386-sequent
+	e500v[12]-*)
+		cpu=powerpc
+		os=$os"spe"
 		;;
-	sh5el)
-		basic_machine=sh5le-unknown
+	mips3*-*)
+		cpu=mips64
 		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=vxworks
+	ms1-*)
+		cpu=mt
 		;;
-	spur)
-		basic_machine=spur-unknown
+	m68knommu-*)
+		cpu=m68k
+		os=linux
 		;;
-	st2000)
-		basic_machine=m68k-tandem
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	openrisc-*)
+		cpu=or32
 		;;
-	sun2)
-		basic_machine=m68000-sun
+	parisc-*)
+		cpu=hppa
+		os=linux
 		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	sun4)
-		basic_machine=sparc-sun
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=linux-gnu
+	pentium4-*)
+		cpu=i786
 		;;
-	tx39)
-		basic_machine=mipstx39-unknown
+	pc98-*)
+		cpu=i386
 		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
+	ppc-* | ppcbe-*)
+		cpu=powerpc
 		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
 		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
+	ppc64-*)
+		cpu=powerpc64
 		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=none
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
 		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=proelf
+	sb1-*)
+		cpu=mipsisa64sb1
 		;;
-	x64)
-		basic_machine=x86_64-pc
+	sb1el-*)
+		cpu=mipsisa64sb1el
 		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
+	sh5e[lb]-*)
+		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
 		;;
-	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+	spur-*)
+		cpu=spur
 		;;
-	none)
-		basic_machine=none-none
-		os=${os:-none}
+	strongarm-* | thumb-*)
+		cpu=arm
 		;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
+	tx39-*)
+		cpu=mipstx39
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+	tx39el-*)
+		cpu=mipstx39el
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	x64-*)
+		cpu=x86_64
 		;;
-	romp)
-		basic_machine=romp-ibm
+	xscale-* | xscalee[bl]-*)
+		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
 		;;
-	mmix)
-		basic_machine=mmix-knuth
+
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		os=${os:-elf}
 		;;
-	rs6000)
-		basic_machine=rs6000-ibm
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
 		;;
-	vax)
-		basic_machine=vax-dec
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
 		;;
-	pdp11)
-		basic_machine=pdp11-dec
+	crx-*)
+		os=${os:-elf}
 		;;
-	we32k)
-		basic_machine=we32k-att
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	s390-*)
+		cpu=s390
+		vendor=ibm
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	s390x-*)
+		cpu=s390x
+		vendor=ibm
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	tile*-*)
+		os=${os:-linux-gnu}
 		;;
+
 	*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb \
+			| arm  | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv64 \
+			| rl78 | romp | rs6000 | rx \
+			| score \
+			| sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| wasm32 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1356,7 +1341,7 @@ case $os in
 	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
 	     | aos* | aros* | cloudabi* | sortix* \
 	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
-	     | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
 	     | knetbsd* | mirbsd* | netbsd* \
 	     | bitrig* | openbsd* | solidbsd* | libertybsd* \
 	     | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
@@ -1376,12 +1361,12 @@ case $os in
 	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
 	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
 	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
-	     | midnightbsd*)
+	     | midnightbsd* | amdhsa*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
+		case $cpu in
+		    x86 | i*86)
 			;;
 		    *)
 			os=nto-$os
@@ -1507,7 +1492,7 @@ case $os in
 		# Until real need of OS specific support for
 		# particular features comes up, bare metal
 		# configurations are quite functional.
-		case $basic_machine in
+		case $cpu in
 		    arm*)
 			os=eabi
 			;;
@@ -1541,7 +1526,7 @@ else
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+case $cpu-$vendor in
 	score-*)
 		os=elf
 		;;
@@ -1722,9 +1707,8 @@ fi
 
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
+case $vendor in
+	unknown)
 		case $os in
 			riscix*)
 				vendor=acorn
@@ -1793,11 +1777,10 @@ case $basic_machine in
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo "$basic_machine-$os"
+echo "$cpu-$vendor-$os"
 exit
 
 # Local variables:
Jeff Johnston Jan. 15, 2019, 7:15 p.m. | #8
I have updated config.sub and config.guess from gcc master branch.

-- Jeff J.

On Tue, Jan 15, 2019 at 12:24 PM Andrew Stubbs <ams@codesourcery.com> wrote:

> On 15/01/2019 17:09, Jeff Johnston wrote:

> > Patch checked in sans config.sub which we normally sync with gcc.  When

> > gcc has the updated

> > config.sub, post to the list to ask for a sync.  I have added the

> > license info to COPYING.NEWLIB.

>

> Awesome! :-)

>

> The GNU config project was updated a few weeks ago, and GCC has since

> imported that.

>

> I've attached the diff.

>

> Andrew

>

Patch

AMD GCN Port

2019-01-10  Andrew Stubbs  <ams@codesourcery.com>
	    Tom de Vries  <tom@codesourcery.com>
	    Julian Brown  <julian@codesourcery.com>
	    Joseph Myers  <joseph@codesourcery.com>

	newlib/
	* config.sub: Copy from GNU config.
	* configure.host: Add amdgcn.
	* libc/include/machine/ieeefp.h: Configure for __AMDGCN__.
	* libc/include/sys/config.h (__DYNAMIC_REENT__): Define for __AMDGCN__.
	* libc/machine/amdgcn/Makefile.am: New file.
	* libc/machine/amdgcn/abort.c: New file.
	* libc/machine/amdgcn/atexit.c: New file.
	* libc/machine/amdgcn/close.c: New file.
	* libc/machine/amdgcn/configure.in: New file.
	* libc/machine/amdgcn/exit-value.h: New file.
	* libc/machine/amdgcn/exit.c: New file.
	* libc/machine/amdgcn/fstat.c: New file.
	* libc/machine/amdgcn/getreent.c: New file.
	* libc/machine/amdgcn/isatty.c: New file.
	* libc/machine/amdgcn/lseek.c: New file.
	* libc/machine/amdgcn/malloc_support.c: New file.
	* libc/machine/amdgcn/read.c: New file.
	* libc/machine/amdgcn/write.c: New file.
	* libc/machine/configure.in: Add amdgcn directory.
	* libc/ssp/stack_protector.c: Avoid the constructor on AMD GCN.
	* libc/machine/amdgcn/Makefile.in: Regenerate.
	* libc/machine/amdgcn/aclocal.m4: Regenerate.
	* libc/machine/amdgcn/configure: Regenerate.
	* libc/machine/configure: Regenerate.

diff --git a/newlib/configure.host b/newlib/configure.host
index 6c49cb7..149ff8a 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -118,6 +118,10 @@  case "${host_cpu}" in
 	machine_dir=aarch64
 	libm_machine_dir=aarch64
 	;;
+  amdgcn*)
+	newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__"
+	machine_dir=amdgcn
+	;;
   arc*)
 	machine_dir=arc
 	;;
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index a409752..911eeb5 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -452,6 +452,10 @@ 
 #define __IEEE_BIG_ENDIAN
 #endif
 
+#ifdef __AMDGCN__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
 #ifdef __CYGWIN__
 #define __OBSOLETE_MATH_DEFAULT 0
 #endif
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index 49b62eb..d746b15 100644
--- a/newlib/libc/include/sys/config.h
+++ b/newlib/libc/include/sys/config.h
@@ -8,6 +8,10 @@ 
 #define MALLOC_ALIGNMENT 16
 #endif
 
+#ifdef __AMDGCN__
+#define __DYNAMIC_REENT__
+#endif
+
 /* exceptions first */
 #if defined(__H8500__) || defined(__W65__)
 #define __SMALL_BITFIELDS
diff --git a/newlib/libc/machine/amdgcn/Makefile.am b/newlib/libc/machine/amdgcn/Makefile.am
new file mode 100644
index 0000000..ec74346
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/Makefile.am
@@ -0,0 +1,16 @@ 
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = abort.c exit.c atexit.c write.c malloc_support.c \
+		read.c fstat.c isatty.c lseek.c close.c getreent.c
+lib_a_CFLAGS = $(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/machine/amdgcn/abort.c b/newlib/libc/machine/amdgcn/abort.c
new file mode 100644
index 0000000..ccbca72
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/abort.c
@@ -0,0 +1,25 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <signal.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+abort (void)
+{
+  write (2, "GCN Kernel Aborted\n", 19);
+  exit_with_status_and_signal (0, SIGABRT);
+}
diff --git a/newlib/libc/machine/amdgcn/atexit.c b/newlib/libc/machine/amdgcn/atexit.c
new file mode 100644
index 0000000..6745714
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/atexit.c
@@ -0,0 +1,25 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+
+int
+atexit (void (*function)(void))
+{
+  /* Our current implementation of exit does not run functions registered with
+     atexit, so fail here.  */
+  abort ();
+  return 1;
+}
diff --git a/newlib/libc/machine/amdgcn/close.c b/newlib/libc/machine/amdgcn/close.c
new file mode 100644
index 0000000..5bce557
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/close.c
@@ -0,0 +1,24 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int close(int fildes)
+{
+  errno = EIO;
+  return -1;
+}
+
diff --git a/newlib/libc/machine/amdgcn/configure.in b/newlib/libc/machine/amdgcn/configure.in
new file mode 100644
index 0000000..028e9d7
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/configure.in
@@ -0,0 +1,14 @@ 
+dnl This is the newlib/libc/machine/amdgcn configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([Makefile.am])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. 
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/machine/amdgcn/exit-value.h b/newlib/libc/machine/amdgcn/exit-value.h
new file mode 100644
index 0000000..6e88625
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit-value.h
@@ -0,0 +1,48 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#ifndef _AMDGCN_EXIT_VALUE_H_
+#define _AMDGCN_EXIT_VALUE_H_
+
+static inline void  __attribute__((noreturn))
+exit_with_int (int val)
+{
+  /* Write the exit value to the conventional place.  */
+  int *return_value;
+  asm ("s_load_dwordx2	%0, s[8:9], 16 glc\n\t"
+       "s_waitcnt	0" : "=Sg"(return_value));
+  *return_value = val;
+
+  /* Terminate the current kernel.  */
+  asm ("s_dcache_wb");
+  asm ("s_endpgm");
+  __builtin_unreachable ();
+}
+
+static inline void  __attribute__((noreturn))
+exit_with_status_and_signal (int val, int signal)
+{
+  if (signal == 0)
+    val = val & 0xff;
+  else
+    {
+      val = (128 + signal) & 0xff;
+      signal = signal & 0xff;
+    }
+
+  exit_with_int ((0xffff << 16) | (signal << 8) | val);
+}
+
+#endif
diff --git a/newlib/libc/machine/amdgcn/exit.c b/newlib/libc/machine/amdgcn/exit.c
new file mode 100644
index 0000000..bdd532e
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/exit.c
@@ -0,0 +1,23 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014-2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include "exit-value.h"
+
+void __attribute__((noreturn))
+exit (int val)
+{
+  exit_with_status_and_signal (val, 0);
+}
diff --git a/newlib/libc/machine/amdgcn/fstat.c b/newlib/libc/machine/amdgcn/fstat.c
new file mode 100644
index 0000000..b787158
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/fstat.c
@@ -0,0 +1,23 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int fstat(int fildes, struct stat *buf)
+{
+  errno = EIO;
+  return -1;
+}
diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c
new file mode 100644
index 0000000..acf10a9
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/getreent.c
@@ -0,0 +1,79 @@ 
+/* get thread-specific reentrant pointer */
+
+#include <reent.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Copied from the HSA documentation.  */
+typedef struct hsa_signal_s {
+  uint64_t handle;
+} hsa_signal_t;
+typedef struct hsa_kernel_dispatch_packet_s {
+  uint16_t header ;
+  uint16_t setup;
+  uint16_t workgroup_size_x ;
+  uint16_t workgroup_size_y ;
+  uint16_t workgroup_size_z;
+  uint16_t reserved0;
+  uint32_t grid_size_x ;
+  uint32_t grid_size_y ;
+  uint32_t grid_size_z;
+  uint32_t private_segment_size;
+  uint32_t group_segment_size;
+  uint64_t kernel_object;
+  uint64_t reserved2;
+  hsa_signal_t completion_signal;
+} hsa_kernel_dispatch_packet_t;
+
+struct _reent *
+__getreent (void)
+{
+  /* Place the reent data at the top of the stack allocation.
+     s[0:1] contains a 48-bit private segment base address.
+     s11 contains the offset to the base of the stack.
+     s[4:5] contains the dispatch pointer.
+     
+     WARNING: this code will break if s[0:3] is ever used for anything!  */
+  const register long buffer_descriptor asm("s0");
+  long private_segment = buffer_descriptor & 0x0000ffffffffffff;
+  const register int stack_offset asm("s11");
+  const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4");
+
+  struct data {
+    int marker;
+    struct _reent reent;
+  } *data;
+
+  long stack_base = private_segment + stack_offset;
+  long stack_end = stack_base + dispatch_ptr->private_segment_size * 64;
+  long addr = (stack_end - sizeof(struct data)) & ~7;
+  data = (struct data *)addr;
+
+  register long sp asm("s16");
+  if (sp >= addr)
+    goto stackoverflow;
+
+  /* Place a marker in s3 to indicate that the reent data is initialized.
+     The register is known to hold part of an unused buffer descriptor
+     when the kernel is launched.  This may not be unused forever, but
+     we already used s0 and s1 above, so this doesn't do extra harm.  */
+  register int s3 asm("s3");
+  if (s3 != 123456)
+    {
+      asm("s_mov_b32 s3, 123456");
+      data->marker = 123456;
+
+      __builtin_memset (&data->reent, 0, sizeof(struct _reent));
+      _REENT_INIT_PTR_ZEROED (&data->reent);
+    }
+  else if (data->marker != 123456)
+    goto stackoverflow;
+
+
+  return &data->reent;
+
+stackoverflow:
+    write (2, "GCN Stack Overflow!\n", 20);
+    abort ();
+}
+
diff --git a/newlib/libc/machine/amdgcn/isatty.c b/newlib/libc/machine/amdgcn/isatty.c
new file mode 100644
index 0000000..4268f2c
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/isatty.c
@@ -0,0 +1,23 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int isatty(int fd)
+{
+  errno = EINVAL;
+  return 0;
+}
diff --git a/newlib/libc/machine/amdgcn/lseek.c b/newlib/libc/machine/amdgcn/lseek.c
new file mode 100644
index 0000000..be3220b
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/lseek.c
@@ -0,0 +1,24 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+off_t lseek(int fildes, off_t offset, int whence)
+{
+  errno = ESPIPE;
+  return -1;
+}
+
diff --git a/newlib/libc/machine/amdgcn/malloc_support.c b/newlib/libc/machine/amdgcn/malloc_support.c
new file mode 100644
index 0000000..4848c97
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/malloc_support.c
@@ -0,0 +1,111 @@ 
+/*
+ * Support file for AMDGCN in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <reent.h>
+
+/* _sbrk_r expects us to use the real errno, not the reentrant one.  */
+#include <errno.h>
+#undef errno
+extern int errno;
+
+/* The runtime passes in heap space like this.  */
+struct heap {
+  int64_t size;
+  char data[0];
+};
+
+static char *__heap_ptr = (char*)-1;
+static char *__heap_end = (char*)-1;
+static int __heap_lock = 0;
+static void *__heap_lock_id = NULL;
+static int __heap_lock_cnt = 0;
+
+void *
+sbrk (ptrdiff_t nbytes)
+{
+  if (__heap_ptr == (char *)-1)
+    {
+      /* Find the heap from kernargs.
+         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 heap data is at kernargs[3].  */
+      struct heap *heap = *(struct heap **)(kernargs + 24);
+
+      __heap_ptr = heap->data;
+      __heap_end = __heap_ptr + heap->size;
+    }
+
+  if ((__heap_ptr + nbytes) >= __heap_end)
+    {
+      errno = ENOMEM;
+      return (void*)-1;
+    }
+
+  char *base = __heap_ptr;
+  __heap_ptr += nbytes;
+
+  return base;
+}
+
+void
+__malloc_lock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id == __heap_lock_id)
+    {
+      if (__heap_lock_cnt < 1)
+	abort ();
+      ++__heap_lock_cnt;
+      return;
+    }
+
+  while (__sync_lock_test_and_set (&__heap_lock, 1))
+    /* A sleep seems like it should allow the wavefront to yeild (maybe?)
+       Use the shortest possible sleep time of 1*64 cycles.  */
+    asm volatile ("s_sleep\t1" ::: "memory");
+
+  if (__heap_lock_id != NULL)
+    abort ();
+  if (__heap_lock_cnt != 0)
+    abort ();
+
+  __heap_lock_cnt = 1;
+  __heap_lock_id = id;
+}
+
+void
+__malloc_unlock (struct _reent *reent)
+{
+  void *id = reent;
+
+  if (id != __heap_lock_id)
+    abort ();
+  if (__heap_lock_cnt < 1)
+    abort ();
+
+  --__heap_lock_cnt;
+
+  if (__heap_lock_cnt > 0)
+    return;
+
+  __heap_lock_id = NULL;
+  __sync_lock_release (&__heap_lock);
+}
diff --git a/newlib/libc/machine/amdgcn/read.c b/newlib/libc/machine/amdgcn/read.c
new file mode 100644
index 0000000..97385e9
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/read.c
@@ -0,0 +1,21 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdio.h>
+
+_READ_WRITE_RETURN_TYPE read (int fildes, void *buf, size_t nbyte)
+{
+  return 0;
+}
diff --git a/newlib/libc/machine/amdgcn/write.c b/newlib/libc/machine/amdgcn/write.c
new file mode 100644
index 0000000..ce5bd36
--- /dev/null
+++ b/newlib/libc/machine/amdgcn/write.c
@@ -0,0 +1,88 @@ 
+/*
+ * Support file for amdgcn in newlib.
+ * Copyright (c) 2014, 2017 Mentor Graphics.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+/* 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];
+};
+
+_READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count)
+{
+  if (fd != 1 && fd != 2)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* The output data is at ((void*)kernargs)[2].  */
+  register void **kernargs asm("s8");
+  struct output *data = (struct output *)kernargs[2];
+
+  /* Each output slot allows 256 bytes, so reserve as many as we need. */
+  int slot_count = ((count+1)/256)+1;
+  int index = __atomic_fetch_add (&data->next_output, slot_count,
+				  __ATOMIC_ACQUIRE);
+  for (int c = count;
+       c >= 0 && index < 1000;
+       buf += 256, c -= 256, index++)
+    {
+      if (c < 128)
+	{
+	  memcpy (data->queue[index].msg, buf, c);
+	  data->queue[index].msg[c] = '\0';
+	  data->queue[index].text[0] = '\0';
+	}
+      else if (c < 256)
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, c-128);
+	  data->queue[index].text[c-128] = '\0';
+	}
+      else
+	{
+	  memcpy (data->queue[index].msg, buf, 128);
+	  memcpy (data->queue[index].text, buf+128, 128);
+	}
+
+      data->queue[index].type = 3; /* Raw.  */
+      __atomic_store_n (&data->queue[index].written, 1, __ATOMIC_RELEASE);
+    }
+
+  return count;
+}
diff --git a/newlib/libc/machine/configure.in b/newlib/libc/machine/configure.in
index 8ebe68b..0d4068c 100644
--- a/newlib/libc/machine/configure.in
+++ b/newlib/libc/machine/configure.in
@@ -25,6 +25,7 @@  if test -n "${machine_dir}"; then
   case ${machine_dir} in
 	a29k) AC_CONFIG_SUBDIRS(a29k) ;;
 	aarch64) AC_CONFIG_SUBDIRS(aarch64) ;;
+	amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;;
 	arc) AC_CONFIG_SUBDIRS(arc) ;;
 	arm) AC_CONFIG_SUBDIRS(arm) ;;
 	bfin) AC_CONFIG_SUBDIRS(bfin) ;;
diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c
index ee014b6..cd51543 100644
--- a/newlib/libc/ssp/stack_protector.c
+++ b/newlib/libc/ssp/stack_protector.c
@@ -5,6 +5,11 @@ 
 #include <string.h>
 #include <unistd.h>
 
+#if defined(__AMDGCN__)
+/* GCN does not support constructors, yet.  */
+uintptr_t __stack_chk_guard = 0x00000aff; /* 0, 0, '\n', 255  */
+
+#else
 uintptr_t __stack_chk_guard = 0;
 
 void
@@ -24,6 +29,7 @@  __stack_chk_init (void)
   ((unsigned char *)&__stack_chk_guard)[3] = 255;
 #endif
 }
+#endif
 
 void
 __attribute__((__noreturn__))