runtime: add prefetch functions

The Go 1.8 GC uses prefetch functions.  Add versions for gccgo that
call __builtin_prefetch.  Uncomment the test for them in testAtomic64.
Don't force the check function to return early, as now taking the
address of a local variable in the runtime package does not force it
onto the heap.

Change-Id: I48be1af93586a6c89a53b569217dcb6043466d66
Reviewed-on: https://go-review.googlesource.com/41144
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go
index 99c0f11..9100880 100644
--- a/libgo/go/runtime/runtime1.go
+++ b/libgo/go/runtime/runtime1.go
@@ -112,10 +112,10 @@
 func testAtomic64() {
 	test_z64 = 42
 	test_x64 = 0
-	// prefetcht0(uintptr(unsafe.Pointer(&test_z64)))
-	// prefetcht1(uintptr(unsafe.Pointer(&test_z64)))
-	// prefetcht2(uintptr(unsafe.Pointer(&test_z64)))
-	// prefetchnta(uintptr(unsafe.Pointer(&test_z64)))
+	prefetcht0(uintptr(unsafe.Pointer(&test_z64)))
+	prefetcht1(uintptr(unsafe.Pointer(&test_z64)))
+	prefetcht2(uintptr(unsafe.Pointer(&test_z64)))
+	prefetchnta(uintptr(unsafe.Pointer(&test_z64)))
 	if atomic.Cas64(&test_z64, test_x64, 1) {
 		throw("cas64 failed")
 	}
@@ -151,14 +151,6 @@
 }
 
 func check() {
-
-	// This doesn't currently work for gccgo.  Because escape
-	// analysis is not turned on by default, the code below that
-	// takes the address of local variables causes memory
-	// allocation, but this function is called before the memory
-	// allocator has been initialized.
-	return
-
 	var (
 		a     int8
 		b     uint8
diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go
index 9109e4b..5029446 100644
--- a/libgo/go/runtime/stubs.go
+++ b/libgo/go/runtime/stubs.go
@@ -222,6 +222,25 @@
 //go:linkname time_now time.now
 func time_now() (sec int64, nsec int32)
 
+//extern __builtin_prefetch
+func prefetch(addr unsafe.Pointer, rw int32, locality int32)
+
+func prefetcht0(addr uintptr) {
+	prefetch(unsafe.Pointer(addr), 0, 3)
+}
+
+func prefetcht1(addr uintptr) {
+	prefetch(unsafe.Pointer(addr), 0, 2)
+}
+
+func prefetcht2(addr uintptr) {
+	prefetch(unsafe.Pointer(addr), 0, 1)
+}
+
+func prefetchnta(addr uintptr) {
+	prefetch(unsafe.Pointer(addr), 0, 0)
+}
+
 // For gccgo, expose this for C callers.
 //go:linkname unixnanotime runtime.unixnanotime
 func unixnanotime() int64 {