diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a331db61b3d836f689bdee1ea755a33c6de1f637..bc954f02cbda9cd194479ffc3877ef00249b1bcc 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-14dc8052a09ad0a2226e64ab6b5af69c6923b830
+df6046971233854e5b7533140d4ead095ab69857
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 08947c06b04cabcb7b69e04b1574feedb4413bb7..1e99810f478873789bd5b70d2d3d2da1a0050cd6 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -488,7 +488,6 @@ runtime_files = \
 	$(runtime_thread_files) \
 	runtime/yield.c \
 	$(rtems_task_variable_add_file) \
-	lfstack.c \
 	malloc.c \
 	runtime1.c \
 	sigqueue.c \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 6cbac4278ffd85276b4d7e88b862e01f6e01ceb5..c85ec502236d27d7492c8d671b7f0757f54e0f4d 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -252,8 +252,8 @@ am__objects_5 = go-append.lo go-assert.lo go-breakpoint.lo \
 	env_posix.lo heapdump.lo mcache.lo mcentral.lo \
 	$(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo msize.lo \
 	panic.lo parfor.lo print.lo proc.lo runtime.lo signal_unix.lo \
-	thread.lo $(am__objects_2) yield.lo $(am__objects_3) \
-	lfstack.lo malloc.lo runtime1.lo sigqueue.lo $(am__objects_4)
+	thread.lo $(am__objects_2) yield.lo $(am__objects_3) malloc.lo \
+	runtime1.lo sigqueue.lo $(am__objects_4)
 am_libgo_llgo_la_OBJECTS = $(am__objects_5)
 libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
 libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -884,7 +884,6 @@ runtime_files = \
 	$(runtime_thread_files) \
 	runtime/yield.c \
 	$(rtems_task_variable_add_file) \
-	lfstack.c \
 	malloc.c \
 	runtime1.c \
 	sigqueue.c \
@@ -1562,7 +1561,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unwind.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-varargs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heapdump.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lfstack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_a-go-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_llgo_a-go-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgolibbegin_a-go-libmain.Po@am__quote@
diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go
index 711a551d2785bf90bdcbe4526c15655bcf6265a3..d3443566d9204f245966e2414dd65cd41b2f9fae 100644
--- a/libgo/go/runtime/export_test.go
+++ b/libgo/go/runtime/export_test.go
@@ -6,6 +6,10 @@
 
 package runtime
 
+import (
+	"unsafe"
+)
+
 //var Fadd64 = fadd64
 //var Fsub64 = fsub64
 //var Fmul64 = fmul64
@@ -32,11 +36,13 @@ type LFNode struct {
 	Pushcnt uintptr
 }
 
-func lfstackpush_go(head *uint64, node *LFNode)
-func lfstackpop_go(head *uint64) *LFNode
+func LFStackPush(head *uint64, node *LFNode) {
+	lfstackpush(head, (*lfnode)(unsafe.Pointer(node)))
+}
 
-var LFStackPush = lfstackpush_go
-var LFStackPop = lfstackpop_go
+func LFStackPop(head *uint64) *LFNode {
+	return (*LFNode)(unsafe.Pointer(lfstackpop(head)))
+}
 
 type ParFor struct {
 	body   func(*ParFor, uint32)
diff --git a/libgo/go/runtime/lfstack.go b/libgo/go/runtime/lfstack.go
new file mode 100644
index 0000000000000000000000000000000000000000..2f2958c8869cee48054ea7e8a0924b24f76b3ec6
--- /dev/null
+++ b/libgo/go/runtime/lfstack.go
@@ -0,0 +1,50 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lock-free stack.
+// Initialize head to 0, compare with 0 to test for emptiness.
+// The stack does not keep pointers to nodes,
+// so they can be garbage collected if there are no other pointers to nodes.
+// The following code runs only in non-preemptible contexts.
+
+package runtime
+
+import (
+	"runtime/internal/atomic"
+	"unsafe"
+)
+
+// Temporary for C code to call:
+//go:linkname lfstackpush runtime.lfstackpush
+//go:linkname lfstackpop runtime.lfstackpop
+
+func lfstackpush(head *uint64, node *lfnode) {
+	node.pushcnt++
+	new := lfstackPack(node, node.pushcnt)
+	if node1 := lfstackUnpack(new); node1 != node {
+		print("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
+		throw("lfstackpush")
+	}
+	for {
+		old := atomic.Load64(head)
+		node.next = old
+		if atomic.Cas64(head, old, new) {
+			break
+		}
+	}
+}
+
+func lfstackpop(head *uint64) unsafe.Pointer {
+	for {
+		old := atomic.Load64(head)
+		if old == 0 {
+			return nil
+		}
+		node := lfstackUnpack(old)
+		next := atomic.Load64(&node.next)
+		if atomic.Cas64(head, old, next) {
+			return unsafe.Pointer(node)
+		}
+	}
+}
diff --git a/libgo/go/runtime/lfstack_32bit.go b/libgo/go/runtime/lfstack_32bit.go
new file mode 100644
index 0000000000000000000000000000000000000000..6a9920000841266d5ac0e7abe7cd673ebb3d6a1f
--- /dev/null
+++ b/libgo/go/runtime/lfstack_32bit.go
@@ -0,0 +1,19 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 arm nacl armbe m68k mips mipsle mips64p32 mips64p32le mipso32 mipsn32 s390 sparc
+
+package runtime
+
+import "unsafe"
+
+// On 32-bit systems, the stored uint64 has a 32-bit pointer and 32-bit count.
+
+func lfstackPack(node *lfnode, cnt uintptr) uint64 {
+	return uint64(uintptr(unsafe.Pointer(node)))<<32 | uint64(cnt)
+}
+
+func lfstackUnpack(val uint64) *lfnode {
+	return (*lfnode)(unsafe.Pointer(uintptr(val >> 32)))
+}
diff --git a/libgo/go/runtime/lfstack_64bit.go b/libgo/go/runtime/lfstack_64bit.go
index 3b0eb986ce3d8746335741f0b672ca2ce57f5798..213efb10706881f4f808f521c635098fa4f18ef9 100644
--- a/libgo/go/runtime/lfstack_64bit.go
+++ b/libgo/go/runtime/lfstack_64bit.go
@@ -2,9 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build ignore
-
-// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x
+// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x arm64be alpha mipsn64 sparc64
 
 package runtime
 
@@ -41,8 +39,8 @@ func lfstackPack(node *lfnode, cnt uintptr) uint64 {
 }
 
 func lfstackUnpack(val uint64) *lfnode {
-	if GOARCH == "amd64" {
-		// amd64 systems can place the stack above the VA hole, so we need to sign extend
+	if GOARCH == "amd64" || GOOS == "solaris" {
+		// amd64 or Solaris systems can place the stack above the VA hole, so we need to sign extend
 		// val before unpacking.
 		return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> cntBits << 3)))
 	}
diff --git a/libgo/runtime/lfstack.goc b/libgo/runtime/lfstack.goc
deleted file mode 100644
index 5ab1baa436ebbe71bb9d8beeabb5c022f8a2130c..0000000000000000000000000000000000000000
--- a/libgo/runtime/lfstack.goc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lock-free stack.
-
-package runtime
-#include "runtime.h"
-#include "arch.h"
-
-#if __SIZEOF_POINTER__ == 8
-// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
-// Use low-order three bits as ABA counter.
-// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
-# if defined(__sparc__) || (defined(__sun__) && defined(__amd64__))
-static inline uint64 lfPack(LFNode *node, uintptr cnt) {
-	return ((uint64)(node)) | ((cnt)&7);
-}
-static inline LFNode* lfUnpack(uint64 val) {
-	return (LFNode*)(val&~7);
-}
-# else
-#  if defined(__aarch64__)
-// Depending on the kernel options, pointers on arm64 can have up to 48 significant
-// bits (see https://www.kernel.org/doc/Documentation/arm64/memory.txt).
-#   define PTR_BITS 48
-#  else
-// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
-// So we use 17msb of pointers as ABA counter.
-#   define PTR_BITS 47
-#  endif
-# define CNT_BITS (64 - PTR_BITS + 3)
-static inline uint64 lfPack(LFNode *node, uintptr cnt) {
-	return ((uint64)(node)<<(64-PTR_BITS)) | (cnt&(((1<<CNT_BITS)-1)));
-}
-static inline LFNode* lfUnpack(uint64 val) {
-	return (LFNode*)((val >> CNT_BITS) << 3);
-}
-# endif
-#else
-static inline uint64 lfPack(LFNode *node, uintptr cnt) {
-	return ((uint64)(uintptr)(node)<<32) | cnt;
-}
-static inline LFNode* lfUnpack(uint64 val) {
-	return (LFNode*)(uintptr)(val >> 32);
-}
-#endif
-
-void
-runtime_lfstackpush(uint64 *head, LFNode *node)
-{
-	uint64 old, new;
-
-	if(node != lfUnpack(lfPack(node, 0))) {
-		runtime_printf("p=%p\n", node);
-		runtime_throw("runtime_lfstackpush: invalid pointer");
-	}
-
-	node->pushcnt++;
-	new = lfPack(node, node->pushcnt);
-	for(;;) {
-		old = runtime_atomicload64(head);
-		node->next = lfUnpack(old);
-		if(runtime_cas64(head, old, new))
-			break;
-	}
-}
-
-LFNode*
-runtime_lfstackpop(uint64 *head)
-{
-	LFNode *node, *node2;
-	uint64 old, new;
-
-	for(;;) {
-		old = runtime_atomicload64(head);
-		if(old == 0)
-			return nil;
-		node = lfUnpack(old);
-		node2 = runtime_atomicloadp(&node->next);
-		new = 0;
-		if(node2 != nil)
-			new = lfPack(node2, node2->pushcnt);
-		if(runtime_cas64(head, old, new))
-			return node;
-	}
-}
-
-func lfstackpush_go(head *uint64, node *LFNode) {
-	runtime_lfstackpush(head, node);
-}
-
-func lfstackpop_go(head *uint64) (node *LFNode) {
-	node = runtime_lfstackpop(head);
-}
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 8a91429e94ad96d9a98dfb4597f778bc19dafe4d..8be0df4c17deed3d1a165f86daf76f15772da94f 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -67,7 +67,7 @@ typedef struct	FixAlloc	FixAlloc;
 typedef	struct	hchan		Hchan;
 typedef	struct	timer		Timer;
 typedef	struct	gcstats		GCStats;
-typedef	struct	LFNode		LFNode;
+typedef	struct	lfnode		LFNode;
 typedef	struct	ParFor		ParFor;
 typedef	struct	ParForThread	ParForThread;
 typedef	struct	cgoMal		CgoMal;
@@ -178,13 +178,6 @@ enum {
 };
 #endif
 
-// Lock-free stack node.
-struct LFNode
-{
-	LFNode	*next;
-	uintptr	pushcnt;
-};
-
 // Parallel for descriptor.
 struct ParFor
 {
@@ -461,7 +454,8 @@ bool	runtime_notetsleepg(Note*, int64)  // false - timeout
  */
 void	runtime_lfstackpush(uint64 *head, LFNode *node)
   __asm__ (GOSYM_PREFIX "runtime.lfstackpush");
-LFNode*	runtime_lfstackpop(uint64 *head);
+void*	runtime_lfstackpop(uint64 *head)
+  __asm__ (GOSYM_PREFIX "runtime.lfstackpop");
 
 /*
  * Parallel for over [0, n).