[dev.cc] runtime: convert remaining windows C code to Go

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/177090043
diff --git a/src/runtime/netpoll_windows.go b/src/runtime/netpoll_windows.go
index 8a15f18..23d5dc0 100644
--- a/src/runtime/netpoll_windows.go
+++ b/src/runtime/netpoll_windows.go
@@ -152,5 +152,5 @@
 	}
 	op.errno = errno
 	op.qty = qty
-	netpollready(gpp, op.pd, mode)
+	netpollready((**g)(noescape(unsafe.Pointer(gpp))), op.pd, mode)
 }
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
new file mode 100644
index 0000000..abd2297
--- /dev/null
+++ b/src/runtime/os1_windows.go
@@ -0,0 +1,564 @@
+// Copyright 2009 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.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
+//go:cgo_import_dynamic runtime._CloseHandle CloseHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateEventA CreateEventA "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateThread CreateThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA "kernel32.dll"
+//go:cgo_import_dynamic runtime._CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
+//go:cgo_import_dynamic runtime._CryptGenRandom CryptGenRandom "advapi32.dll"
+//go:cgo_import_dynamic runtime._CryptReleaseContext CryptReleaseContext "advapi32.dll"
+//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._ExitProcess ExitProcess "kernel32.dll"
+//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA "kernel32.dll"
+//go:cgo_import_dynamic runtime._NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
+//go:cgo_import_dynamic runtime._ResumeThread ResumeThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetEvent SetEvent "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer "kernel32.dll"
+//go:cgo_import_dynamic runtime._Sleep Sleep "kernel32.dll"
+//go:cgo_import_dynamic runtime._SuspendThread SuspendThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject "kernel32.dll"
+//go:cgo_import_dynamic runtime._WriteFile WriteFile "kernel32.dll"
+//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod "winmm.dll"
+
+var (
+	_AddVectoredExceptionHandler,
+	_CloseHandle,
+	_CreateEventA,
+	_CreateThread,
+	_CreateWaitableTimerA,
+	_CryptAcquireContextW,
+	_CryptGenRandom,
+	_CryptReleaseContext,
+	_DuplicateHandle,
+	_ExitProcess,
+	_FreeEnvironmentStringsW,
+	_GetEnvironmentStringsW,
+	_GetProcAddress,
+	_GetStdHandle,
+	_GetSystemInfo,
+	_GetThreadContext,
+	_LoadLibraryW,
+	_LoadLibraryA,
+	_NtWaitForSingleObject,
+	_ResumeThread,
+	_SetConsoleCtrlHandler,
+	_SetEvent,
+	_SetProcessPriorityBoost,
+	_SetThreadPriority,
+	_SetUnhandledExceptionFilter,
+	_SetWaitableTimer,
+	_Sleep,
+	_SuspendThread,
+	_WaitForSingleObject,
+	_WriteFile,
+	_timeBeginPeriod stdFunction
+)
+
+var _GetQueuedCompletionStatusEx stdFunction
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func externalthreadhandler()
+func exceptiontramp()
+func firstcontinuetramp()
+func lastcontinuetramp()
+
+//go:nosplit
+func getLoadLibrary() uintptr {
+	return uintptr(unsafe.Pointer(_LoadLibraryW))
+}
+
+//go:nosplit
+func getGetProcAddress() uintptr {
+	return uintptr(unsafe.Pointer(_GetProcAddress))
+}
+
+func getproccount() int32 {
+	var info systeminfo
+	stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
+	return int32(info.dwnumberofprocessors)
+}
+
+const (
+	currentProcess = ^uintptr(0) // -1 = current process
+	currentThread  = ^uintptr(1) // -2 = current thread
+)
+
+var (
+	kernel32Name                    = []byte("kernel32.dll\x00")
+	addVectoredContinueHandlerName  = []byte("AddVectoredContinueHandler\x00")
+	getQueuedCompletionStatusExName = []byte("GetQueuedCompletionStatusEx\x00")
+)
+
+func osinit() {
+	setBadSignalMsg()
+
+	kernel32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32Name[0])))
+
+	externalthreadhandlerp = funcPC(externalthreadhandler)
+
+	stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
+	addVectoredContinueHandler := uintptr(0)
+	if kernel32 != 0 {
+		addVectoredContinueHandler = stdcall2(_GetProcAddress, kernel32, uintptr(unsafe.Pointer(&addVectoredContinueHandlerName[0])))
+	}
+	if addVectoredContinueHandler == 0 || unsafe.Sizeof(&kernel32) == 4 {
+		// use SetUnhandledExceptionFilter for windows-386 or
+		// if VectoredContinueHandler is unavailable.
+		// note: SetUnhandledExceptionFilter handler won't be called, if debugging.
+		stdcall1(_SetUnhandledExceptionFilter, funcPC(lastcontinuetramp))
+	} else {
+		stdcall2(stdFunction(unsafe.Pointer(addVectoredContinueHandler)), 1, funcPC(firstcontinuetramp))
+		stdcall2(stdFunction(unsafe.Pointer(addVectoredContinueHandler)), 0, funcPC(lastcontinuetramp))
+	}
+
+	stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
+
+	stdcall1(_timeBeginPeriod, 1)
+
+	ncpu = getproccount()
+
+	// Windows dynamic priority boosting assumes that a process has different types
+	// of dedicated threads -- GUI, IO, computational, etc. Go processes use
+	// equivalent threads that all do a mix of GUI, IO, computations, etc.
+	// In such context dynamic priority boosting does nothing but harm, so we turn it off.
+	stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
+
+	if kernel32 != 0 {
+		_GetQueuedCompletionStatusEx = stdFunction(unsafe.Pointer(stdcall2(_GetProcAddress, kernel32, uintptr(unsafe.Pointer(&getQueuedCompletionStatusExName[0])))))
+	}
+}
+
+var random_data [_HashRandomBytes]byte
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+	const (
+		prov_rsa_full       = 1
+		crypt_verifycontext = 0xF0000000
+	)
+	var handle uintptr
+	*rnd = nil
+	*rnd_len = 0
+	if stdcall5(_CryptAcquireContextW, uintptr(unsafe.Pointer(&handle)), 0, 0, prov_rsa_full, crypt_verifycontext) != 0 {
+		if stdcall3(_CryptGenRandom, handle, _HashRandomBytes, uintptr(unsafe.Pointer(&random_data[0]))) != 0 {
+			*rnd = unsafe.Pointer(&random_data[0])
+			*rnd_len = _HashRandomBytes
+		}
+		stdcall2(_CryptReleaseContext, handle, 0)
+	}
+}
+
+func goenvs() {
+	var p *uint16
+
+	env := (*uint16)(unsafe.Pointer(stdcall0(_GetEnvironmentStringsW)))
+
+	n := 0
+	for p = env; *p != 0; n++ {
+		p = (*uint16)(add(unsafe.Pointer(p), uintptr(findnullw(p)+1)))
+	}
+
+	envs = makeStringSlice(int(n))
+
+	p = env
+	for i := 0; i < n; i++ {
+		envs[i] = gostringw(p)
+		p = (*uint16)(add(unsafe.Pointer(p), uintptr(findnullw(p)+1)))
+	}
+
+	stdcall1(_FreeEnvironmentStringsW, uintptr(unsafe.Pointer(env)))
+}
+
+//go:nosplit
+func exit(code int32) {
+	stdcall1(_ExitProcess, uintptr(code))
+}
+
+//go:nosplit
+func write(fd uintptr, buf unsafe.Pointer, n int32) int32 {
+	const (
+		_STD_OUTPUT_HANDLE = ^uintptr(10) // -11
+		_STD_ERROR_HANDLE  = ^uintptr(11) // -12
+	)
+	var handle uintptr
+	switch fd {
+	case 1:
+		handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
+	case 2:
+		handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
+	default:
+		// assume fd is real windows handle.
+		handle = fd
+	}
+	var written uint32
+	stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
+	return int32(written)
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+	// store ms in ns to save stack space
+	if ns < 0 {
+		ns = _INFINITE
+	} else {
+		ns = int64(timediv(ns, 1000000, nil))
+		if ns == 0 {
+			ns = 1
+		}
+	}
+	if stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(ns)) != 0 {
+		return -1 // timeout
+	}
+	return 0
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+	stdcall1(_SetEvent, mp.waitsema)
+}
+
+//go:nosplit
+func semacreate() uintptr {
+	return stdcall4(_CreateEventA, 0, 0, 0, 0)
+}
+
+func newosproc(mp *m, stk unsafe.Pointer) {
+	const _STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000
+	thandle := stdcall6(_CreateThread, 0, 0x20000,
+		funcPC(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
+		_STACK_SIZE_PARAM_IS_A_RESERVATION, 0)
+	if thandle == 0 {
+		println("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")")
+		gothrow("runtime.newosproc")
+	}
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+	var thandle uintptr
+	stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
+	atomicstoreuintptr(&getg().m.thread, thandle)
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+	tp := &getg().m.thread
+	stdcall1(_CloseHandle, *tp)
+	*tp = 0
+}
+
+// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
+type _KSYSTEM_TIME struct {
+	LowPart   uint32
+	High1Time int32
+	High2Time int32
+}
+
+const (
+	_INTERRUPT_TIME = 0x7ffe0008
+	_SYSTEM_TIME    = 0x7ffe0014
+)
+
+//go:nosplit
+func systime(addr uintptr) int64 {
+	timeaddr := (*_KSYSTEM_TIME)(unsafe.Pointer(addr))
+
+	var t _KSYSTEM_TIME
+	for i := 1; i < 10000; i++ {
+		// these fields must be read in that order (see URL above)
+		t.High1Time = timeaddr.High1Time
+		t.LowPart = timeaddr.LowPart
+		t.High2Time = timeaddr.High2Time
+		if t.High1Time == t.High2Time {
+			return int64(t.High1Time)<<32 | int64(t.LowPart)
+		}
+		if (i % 100) == 0 {
+			osyield()
+		}
+	}
+	systemstack(func() {
+		gothrow("interrupt/system time is changing too fast")
+	})
+	return 0
+}
+
+//go:nosplit
+func unixnano() int64 {
+	return (systime(_SYSTEM_TIME) - 116444736000000000) * 100
+}
+
+//go:nosplit
+func nanotime() int64 {
+	return systime(_INTERRUPT_TIME) * 100
+}
+
+// Calling stdcall on os stack.
+//go:nosplit
+func stdcall(fn stdFunction) uintptr {
+	gp := getg()
+	mp := gp.m
+	mp.libcall.fn = uintptr(unsafe.Pointer(fn))
+
+	if mp.profilehz != 0 {
+		// leave pc/sp for cpu profiler
+		mp.libcallg = gp
+		mp.libcallpc = getcallerpc(unsafe.Pointer(&fn))
+		// sp must be the last, because once async cpu profiler finds
+		// all three values to be non-zero, it will use them
+		mp.libcallsp = getcallersp(unsafe.Pointer(&fn))
+	}
+	asmcgocall(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&mp.libcall))
+	mp.libcallsp = 0
+	return mp.libcall.r1
+}
+
+//go:nosplit
+func stdcall0(fn stdFunction) uintptr {
+	mp := getg().m
+	mp.libcall.n = 0
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall1(fn stdFunction, a0 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 1
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 2
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 3
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 4
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 5
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 6
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
+	mp := getg().m
+	mp.libcall.n = 7
+	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+	return stdcall(fn)
+}
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func usleep1(usec uint32)
+
+//go:nosplit
+func osyield() {
+	usleep1(1)
+}
+
+//go:nosplit
+func usleep(us uint32) {
+	// Have 1us units; want 100ns units.
+	usleep1(10 * us)
+}
+
+func issigpanic(code uint32) uint32 {
+	switch code {
+	default:
+		return 0
+	case _EXCEPTION_ACCESS_VIOLATION:
+	case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+	case _EXCEPTION_INT_OVERFLOW:
+	case _EXCEPTION_FLT_DENORMAL_OPERAND:
+	case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
+	case _EXCEPTION_FLT_INEXACT_RESULT:
+	case _EXCEPTION_FLT_OVERFLOW:
+	case _EXCEPTION_FLT_UNDERFLOW:
+	case _EXCEPTION_BREAKPOINT:
+	}
+	return 1
+}
+
+func initsig() {
+	/*
+		// TODO(brainman): I don't think we need that bit of code
+		// following line keeps these functions alive at link stage
+		// if there's a better way please write it here
+		void *e = runtime·exceptiontramp;
+		void *f = runtime·firstcontinuetramp;
+		void *l = runtime·lastcontinuetramp;
+		USED(e);
+		USED(f);
+		USED(l);
+	*/
+}
+
+func ctrlhandler1(_type uint32) uint32 {
+	var s uint32
+
+	switch _type {
+	case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
+		s = _SIGINT
+	default:
+		return 0
+	}
+
+	if sigsend(s) {
+		return 1
+	}
+	exit(2) // SIGINT, SIGTERM, etc
+	return 0
+}
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func profileloop()
+
+var profiletimer uintptr
+
+func profilem(mp *m) {
+	var r *context
+	rbuf := make([]byte, unsafe.Sizeof(*r)+15)
+
+	tls := &mp.tls[0]
+	if mp == &m0 {
+		tls = &tls0[0]
+	}
+	gp := *((**g)(unsafe.Pointer(tls)))
+
+	// align Context to 16 bytes
+	r = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&rbuf[15]))) &^ 15))
+	r.contextflags = _CONTEXT_CONTROL
+	stdcall2(_GetThreadContext, mp.thread, uintptr(unsafe.Pointer(r)))
+	dosigprof(r, gp, mp)
+}
+
+func profileloop1() {
+	stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
+
+	for {
+		stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
+		first := (*m)(atomicloadp(unsafe.Pointer(&allm)))
+		for mp := first; mp != nil; mp = mp.alllink {
+			thread := atomicloaduintptr(&mp.thread)
+			// Do not profile threads blocked on Notes,
+			// this includes idle worker threads,
+			// idle timer thread, idle heap scavenger, etc.
+			if thread == 0 || mp.profilehz == 0 || mp.blocked {
+				continue
+			}
+			stdcall1(_SuspendThread, thread)
+			if mp.profilehz != 0 && !mp.blocked {
+				profilem(mp)
+			}
+			stdcall1(_ResumeThread, thread)
+		}
+	}
+}
+
+var cpuprofilerlock mutex
+
+func resetcpuprofiler(hz int32) {
+	lock(&cpuprofilerlock)
+	if profiletimer == 0 {
+		timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
+		atomicstoreuintptr(&profiletimer, timer)
+		thread := stdcall6(_CreateThread, 0, 0, funcPC(profileloop), 0, 0, 0)
+		stdcall2(_SetThreadPriority, thread, _THREAD_PRIORITY_HIGHEST)
+		stdcall1(_CloseHandle, thread)
+	}
+	unlock(&cpuprofilerlock)
+
+	ms := int32(0)
+	due := ^int64(^uint64(1 << 63))
+	if hz > 0 {
+		ms = 1000 / hz
+		if ms == 0 {
+			ms = 1
+		}
+		due = int64(ms) * -10000
+	}
+	stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
+	atomicstore((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
+}
+
+func memlimit() uintptr {
+	return 0
+}
+
+var (
+	badsignalmsg [100]byte
+	badsignallen int32
+)
+
+func setBadSignalMsg() {
+	const msg = "runtime: signal received on thread not created by Go.\n"
+	for i, c := range msg {
+		badsignalmsg[i] = byte(c)
+		badsignallen++
+	}
+}
+
+func crash() {
+	// TODO: This routine should do whatever is needed
+	// to make the Windows program abort/crash as it
+	// would if Go was not intercepting signals.
+	// On Unix the routine would remove the custom signal
+	// handler and then raise a signal (like SIGABRT).
+	// Something like that should happen here.
+	// It's okay to leave this empty for now: if crash returns
+	// the ordinary exit-after-panic happens.
+}
diff --git a/src/runtime/os1_windows_386.go b/src/runtime/os1_windows_386.go
new file mode 100644
index 0000000..0afef91
--- /dev/null
+++ b/src/runtime/os1_windows_386.go
@@ -0,0 +1,118 @@
+// Copyright 2009 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.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+var text struct{}
+
+func dumpregs(r *context) {
+	print("eax     ", hex(r.eax), "\n")
+	print("ebx     ", hex(r.ebx), "\n")
+	print("ecx     ", hex(r.ecx), "\n")
+	print("edx     ", hex(r.edx), "\n")
+	print("edi     ", hex(r.edi), "\n")
+	print("esi     ", hex(r.esi), "\n")
+	print("ebp     ", hex(r.ebp), "\n")
+	print("esp     ", hex(r.esp), "\n")
+	print("eip     ", hex(r.eip), "\n")
+	print("eflags  ", hex(r.eflags), "\n")
+	print("cs      ", hex(r.segcs), "\n")
+	print("fs      ", hex(r.segfs), "\n")
+	print("gs      ", hex(r.seggs), "\n")
+}
+
+func isgoexception(info *exceptionrecord, r *context) bool {
+	// Only handle exception if executing instructions in Go binary
+	// (not Windows library code).
+	if r.eip < uint32(uintptr(unsafe.Pointer(&text))) || uint32(uintptr(unsafe.Pointer(&etext))) < r.eip {
+		return false
+	}
+
+	if issigpanic(info.exceptioncode) == 0 {
+		return false
+	}
+
+	return true
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+	if !isgoexception(info, r) {
+		return _EXCEPTION_CONTINUE_SEARCH
+	}
+
+	// Make it look like a call to the signal func.
+	// Have to pass arguments out of band since
+	// augmenting the stack frame would break
+	// the unwinding code.
+	gp.sig = info.exceptioncode
+	gp.sigcode0 = uintptr(info.exceptioninformation[0])
+	gp.sigcode1 = uintptr(info.exceptioninformation[1])
+	gp.sigpc = uintptr(r.eip)
+
+	// Only push runtime·sigpanic if r->eip != 0.
+	// If r->eip == 0, probably panicked because of a
+	// call to a nil func.  Not pushing that onto sp will
+	// make the trace look like a call to runtime·sigpanic instead.
+	// (Otherwise the trace will end at runtime·sigpanic and we
+	// won't get to see who faulted.)
+	if r.eip != 0 {
+		sp := unsafe.Pointer(uintptr(r.esp))
+		sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
+		*((*uintptr)(sp)) = uintptr(r.eip)
+		r.esp = uint32(uintptr(sp))
+	}
+	r.eip = uint32(funcPC(sigpanic))
+	return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+	_g_ := getg()
+
+	if panicking != 0 { // traceback already printed
+		exit(2)
+	}
+	panicking = 1
+
+	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.eip), "\n")
+
+	print("PC=", hex(r.eip), "\n")
+	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+		print("signal arrived during cgo execution\n")
+		gp = _g_.m.lockedg
+	}
+	print("\n")
+
+	var docrash bool
+	if gotraceback(&docrash) > 0 {
+		tracebacktrap(uintptr(r.eip), uintptr(r.esp), 0, gp)
+		tracebackothers(gp)
+		dumpregs(r)
+	}
+
+	if docrash {
+		crash()
+	}
+
+	exit(2)
+	return 0 // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func dosigprof(r *context, gp *g, mp *m) {
+	sigprof((*byte)(unsafe.Pointer(uintptr(r.eip))), (*byte)(unsafe.Pointer(uintptr(r.esp))), nil, gp, mp)
+}
diff --git a/src/runtime/os1_windows_amd64.go b/src/runtime/os1_windows_amd64.go
new file mode 100644
index 0000000..0d21b38
--- /dev/null
+++ b/src/runtime/os1_windows_amd64.go
@@ -0,0 +1,137 @@
+// Copyright 2011 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.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+var text struct{}
+
+func dumpregs(r *context) {
+	print("rax     ", hex(r.rax), "\n")
+	print("rbx     ", hex(r.rbx), "\n")
+	print("rcx     ", hex(r.rcx), "\n")
+	print("rdi     ", hex(r.rdi), "\n")
+	print("rsi     ", hex(r.rsi), "\n")
+	print("rbp     ", hex(r.rbp), "\n")
+	print("rsp     ", hex(r.rsp), "\n")
+	print("r8      ", hex(r.r8), "\n")
+	print("r9      ", hex(r.r9), "\n")
+	print("r10     ", hex(r.r10), "\n")
+	print("r11     ", hex(r.r11), "\n")
+	print("r12     ", hex(r.r12), "\n")
+	print("r13     ", hex(r.r13), "\n")
+	print("r14     ", hex(r.r14), "\n")
+	print("r15     ", hex(r.r15), "\n")
+	print("rip     ", hex(r.rip), "\n")
+	print("rflags  ", hex(r.eflags), "\n")
+	print("cs      ", hex(r.segcs), "\n")
+	print("fs      ", hex(r.segfs), "\n")
+	print("gs      ", hex(r.seggs), "\n")
+}
+
+func isgoexception(info *exceptionrecord, r *context) bool {
+	// Only handle exception if executing instructions in Go binary
+	// (not Windows library code).
+	if r.rip < uint64(uintptr(unsafe.Pointer(&text))) || uint64(uintptr(unsafe.Pointer(&etext))) < r.rip {
+		return false
+	}
+
+	if issigpanic(info.exceptioncode) == 0 {
+		return false
+	}
+
+	return true
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+
+func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+	if !isgoexception(info, r) {
+		return _EXCEPTION_CONTINUE_SEARCH
+	}
+
+	// Make it look like a call to the signal func.
+	// Have to pass arguments out of band since
+	// augmenting the stack frame would break
+	// the unwinding code.
+	gp.sig = info.exceptioncode
+	gp.sigcode0 = uintptr(info.exceptioninformation[0])
+	gp.sigcode1 = uintptr(info.exceptioninformation[1])
+	gp.sigpc = uintptr(r.rip)
+
+	// Only push runtime·sigpanic if r->rip != 0.
+	// If r->rip == 0, probably panicked because of a
+	// call to a nil func.  Not pushing that onto sp will
+	// make the trace look like a call to runtime·sigpanic instead.
+	// (Otherwise the trace will end at runtime·sigpanic and we
+	// won't get to see who faulted.)
+	if r.rip != 0 {
+		sp := unsafe.Pointer(uintptr(r.rsp))
+		sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
+		*((*uintptr)(sp)) = uintptr(r.rip)
+		r.rsp = uint64(uintptr(sp))
+	}
+	r.rip = uint64(funcPC(sigpanic))
+	return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// It seems Windows searches ContinueHandler's list even
+// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
+// firstcontinuehandler will stop that search,
+// if exceptionhandler did the same earlier.
+func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+	if !isgoexception(info, r) {
+		return _EXCEPTION_CONTINUE_SEARCH
+	}
+	return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+	_g_ := getg()
+
+	if panicking != 0 { // traceback already printed
+		exit(2)
+	}
+	panicking = 1
+
+	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.rip), "\n")
+
+	print("PC=", hex(r.rip), "\n")
+	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+		print("signal arrived during cgo execution\n")
+		gp = _g_.m.lockedg
+	}
+	print("\n")
+
+	var docrash bool
+	if gotraceback(&docrash) > 0 {
+		tracebacktrap(uintptr(r.rip), uintptr(r.rsp), 0, gp)
+		tracebackothers(gp)
+		dumpregs(r)
+	}
+
+	if docrash {
+		crash()
+	}
+
+	exit(2)
+	return 0 // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func dosigprof(r *context, gp *g, mp *m) {
+	sigprof((*byte)(unsafe.Pointer(uintptr(r.rip))), (*byte)(unsafe.Pointer(uintptr(r.rsp))), nil, gp, mp)
+}
diff --git a/src/runtime/os2_windows.go b/src/runtime/os2_windows.go
new file mode 100644
index 0000000..d5b1f47
--- /dev/null
+++ b/src/runtime/os2_windows.go
@@ -0,0 +1,25 @@
+// Copyright 2009 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.
+
+package runtime
+
+import "unsafe"
+
+// Call a Windows function with stdcall conventions,
+// and switch to os stack during the call.
+func asmstdcall(fn unsafe.Pointer)
+
+func getlasterror() uint32
+func setlasterror(err uint32)
+
+// Function to be called by windows CreateThread
+// to start new os thread.
+func tstart_stdcall(newm *m) uint32
+
+func ctrlhandler(_type uint32) uint32
+
+// TODO(brainman): should not need those
+const (
+	_NSIG = 65
+)
diff --git a/src/runtime/os_windows.c b/src/runtime/os_windows.c
deleted file mode 100644
index b8b8eda..0000000
--- a/src/runtime/os_windows.c
+++ /dev/null
@@ -1,636 +0,0 @@
-// Copyright 2009 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.
-
-#include "runtime.h"
-#include "type.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "textflag.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-#pragma dynimport runtime·AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
-#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
-#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
-#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
-#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
-#pragma dynimport runtime·CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
-#pragma dynimport runtime·CryptGenRandom CryptGenRandom "advapi32.dll"
-#pragma dynimport runtime·CryptReleaseContext CryptReleaseContext "advapi32.dll"
-#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
-#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
-#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
-#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
-#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
-#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
-#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
-#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
-#pragma dynimport runtime·NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
-#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
-#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
-#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
-#pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
-#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
-#pragma dynimport runtime·SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
-#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
-#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
-#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
-#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
-#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
-#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
-
-extern void *runtime·AddVectoredExceptionHandler;
-extern void *runtime·CloseHandle;
-extern void *runtime·CreateEvent;
-extern void *runtime·CreateThread;
-extern void *runtime·CreateWaitableTimer;
-extern void *runtime·CryptAcquireContextW;
-extern void *runtime·CryptGenRandom;
-extern void *runtime·CryptReleaseContext;
-extern void *runtime·DuplicateHandle;
-extern void *runtime·ExitProcess;
-extern void *runtime·FreeEnvironmentStringsW;
-extern void *runtime·GetEnvironmentStringsW;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetStdHandle;
-extern void *runtime·GetSystemInfo;
-extern void *runtime·GetThreadContext;
-extern void *runtime·LoadLibrary;
-extern void *runtime·LoadLibraryA;
-extern void *runtime·NtWaitForSingleObject;
-extern void *runtime·ResumeThread;
-extern void *runtime·SetConsoleCtrlHandler;
-extern void *runtime·SetEvent;
-extern void *runtime·SetProcessPriorityBoost;
-extern void *runtime·SetThreadPriority;
-extern void *runtime·SetUnhandledExceptionFilter;
-extern void *runtime·SetWaitableTimer;
-extern void *runtime·Sleep;
-extern void *runtime·SuspendThread;
-extern void *runtime·WaitForSingleObject;
-extern void *runtime·WriteFile;
-extern void *runtime·timeBeginPeriod;
-
-#pragma dataflag NOPTR
-void *runtime·GetQueuedCompletionStatusEx;
-
-extern uintptr runtime·externalthreadhandlerp;
-void runtime·externalthreadhandler(void);
-void runtime·exceptiontramp(void);
-void runtime·firstcontinuetramp(void);
-void runtime·lastcontinuetramp(void);
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·getLoadLibrary(void)
-{
-	return (uintptr)runtime·LoadLibrary;
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·getGetProcAddress(void)
-{
-	return (uintptr)runtime·GetProcAddress;
-}
-
-static int32
-getproccount(void)
-{
-	SystemInfo info;
-
-	runtime·stdcall1(runtime·GetSystemInfo, (uintptr)&info);
-	return info.dwNumberOfProcessors;
-}
-
-void
-runtime·osinit(void)
-{
-	void *kernel32;
-	void *addVectoredContinueHandler;
-
-	kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
-
-	runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
-
-	runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·exceptiontramp);
-	addVectoredContinueHandler = nil;
-	if(kernel32 != nil)
-		addVectoredContinueHandler = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"AddVectoredContinueHandler");
-	if(addVectoredContinueHandler == nil || sizeof(void*) == 4) {
-		// use SetUnhandledExceptionFilter for windows-386 or
-		// if VectoredContinueHandler is unavailable.
-		// note: SetUnhandledExceptionFilter handler won't be called, if debugging.
-		runtime·stdcall1(runtime·SetUnhandledExceptionFilter, (uintptr)runtime·lastcontinuetramp);
-	} else {
-		runtime·stdcall2(addVectoredContinueHandler, 1, (uintptr)runtime·firstcontinuetramp);
-		runtime·stdcall2(addVectoredContinueHandler, 0, (uintptr)runtime·lastcontinuetramp);
-	}
-
-	runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
-
-	runtime·stdcall1(runtime·timeBeginPeriod, 1);
-
-	runtime·ncpu = getproccount();
-	
-	// Windows dynamic priority boosting assumes that a process has different types
-	// of dedicated threads -- GUI, IO, computational, etc. Go processes use
-	// equivalent threads that all do a mix of GUI, IO, computations, etc.
-	// In such context dynamic priority boosting does nothing but harm, so we turn it off.
-	runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
-
-	if(kernel32 != nil) {
-		runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
-	}
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	uintptr handle;
-	*rnd = nil;
-	*rnd_len = 0;
-	if(runtime·stdcall5(runtime·CryptAcquireContextW, (uintptr)&handle, (uintptr)nil, (uintptr)nil,
-			   1 /* PROV_RSA_FULL */,
-			   0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
-		static byte random_data[HashRandomBytes];
-		if(runtime·stdcall3(runtime·CryptGenRandom, handle, HashRandomBytes, (uintptr)&random_data[0])) {
-			*rnd = random_data;
-			*rnd_len = HashRandomBytes;
-		}
-		runtime·stdcall2(runtime·CryptReleaseContext, handle, 0);
-	}
-}
-
-void
-runtime·goenvs(void)
-{
-	extern Slice runtime·envs;
-
-	uint16 *env;
-	String *s;
-	int32 i, n;
-	uint16 *p;
-
-	env = runtime·stdcall0(runtime·GetEnvironmentStringsW);
-
-	n = 0;
-	for(p=env; *p; n++)
-		p += runtime·findnullw(p)+1;
-
-	runtime·envs = runtime·makeStringSlice(n);
-	s = (String*)runtime·envs.array;
-
-	p = env;
-	for(i=0; i<n; i++) {
-		s[i] = runtime·gostringw(p);
-		p += runtime·findnullw(p)+1;
-	}
-
-	runtime·stdcall1(runtime·FreeEnvironmentStringsW, (uintptr)env);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·exit(int32 code)
-{
-	runtime·stdcall1(runtime·ExitProcess, code);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·write(uintptr fd, void *buf, int32 n)
-{
-	void *handle;
-	uint32 written;
-
-	written = 0;
-	switch(fd) {
-	case 1:
-		handle = runtime·stdcall1(runtime·GetStdHandle, -11);
-		break;
-	case 2:
-		handle = runtime·stdcall1(runtime·GetStdHandle, -12);
-		break;
-	default:
-		// assume fd is real windows handle.
-		handle = (void*)fd;
-		break;
-	}
-	runtime·stdcall5(runtime·WriteFile, (uintptr)handle, (uintptr)buf, n, (uintptr)&written, 0);
-	return written;
-}
-
-#define INFINITE ((uintptr)0xFFFFFFFF)
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	// store ms in ns to save stack space
-	if(ns < 0)
-		ns = INFINITE;
-	else {
-		ns = runtime·timediv(ns, 1000000, nil);
-		if(ns == 0)
-			ns = 1;
-	}
-	if(runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)g->m->waitsema, ns) != 0)
-		return -1;  // timeout
-	return 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
-	runtime·stdcall1(runtime·SetEvent, mp->waitsema);
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
-	return (uintptr)runtime·stdcall4(runtime·CreateEvent, 0, 0, 0, 0);
-}
-
-#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	void *thandle;
-
-	USED(stk);
-
-	thandle = runtime·stdcall6(runtime·CreateThread,
-		(uintptr)nil, 0x20000, (uintptr)runtime·tstart_stdcall, (uintptr)mp,
-		STACK_SIZE_PARAM_IS_A_RESERVATION, (uintptr)nil);
-	if(thandle == nil) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	USED(mp);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	uintptr thandle;
-
-	// -1 = current process, -2 = current thread
-	runtime·stdcall7(runtime·DuplicateHandle, -1, -2, -1, (uintptr)&thandle, 0, 0, DUPLICATE_SAME_ACCESS);
-	runtime·atomicstoreuintptr(&g->m->thread, thandle);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·stdcall1(runtime·CloseHandle, g->m->thread);
-	g->m->thread = 0;
-}
-
-// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
-typedef struct KSYSTEM_TIME {
-	uint32	LowPart;
-	int32	High1Time;
-	int32	High2Time;
-} KSYSTEM_TIME;
-
-#pragma dataflag NOPTR
-const KSYSTEM_TIME* INTERRUPT_TIME	= (KSYSTEM_TIME*)0x7ffe0008;
-#pragma dataflag NOPTR
-const KSYSTEM_TIME* SYSTEM_TIME		= (KSYSTEM_TIME*)0x7ffe0014;
-
-static void badsystime(void);
-
-#pragma textflag NOSPLIT
-int64
-runtime·systime(KSYSTEM_TIME *timeaddr)
-{
-	KSYSTEM_TIME t;
-	int32 i;
-	void (*fn)(void);
-
-	for(i = 1; i < 10000; i++) {
-		// these fields must be read in that order (see URL above)
-		t.High1Time = timeaddr->High1Time;
-		t.LowPart = timeaddr->LowPart;
-		t.High2Time = timeaddr->High2Time;
-		if(t.High1Time == t.High2Time)
-			return (int64)t.High1Time<<32 | t.LowPart;
-		if((i%100) == 0)
-			runtime·osyield();
-	}
-	fn = badsystime;
-	runtime·onM(&fn);
-	return 0;
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·unixnano(void)
-{
-	return (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
-}
-
-static void
-badsystime(void)
-{
-	runtime·throw("interrupt/system time is changing too fast");
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
-	return runtime·systime(INTERRUPT_TIME) * 100LL;
-}
-
-// Calling stdcall on os stack.
-#pragma textflag NOSPLIT
-static void*
-stdcall(void *fn)
-{
-	g->m->libcall.fn = (uintptr)fn;
-	if(g->m->profilehz != 0) {
-		// leave pc/sp for cpu profiler
-		g->m->libcallg = g;
-		g->m->libcallpc = (uintptr)runtime·getcallerpc(&fn);
-		// sp must be the last, because once async cpu profiler finds
-		// all three values to be non-zero, it will use them
-		g->m->libcallsp = (uintptr)runtime·getcallersp(&fn);
-	}
-	runtime·asmcgocall(runtime·asmstdcall, &g->m->libcall);
-	g->m->libcallsp = 0;
-	return (void*)g->m->libcall.r1;
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall0(void *fn)
-{
-	g->m->libcall.n = 0;
-	g->m->libcall.args = (uintptr)&fn;  // it's unused but must be non-nil, otherwise crashes
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall1(void *fn, uintptr a0)
-{
-	USED(a0);
-	g->m->libcall.n = 1;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall2(void *fn, uintptr a0, uintptr a1)
-{
-	USED(a0, a1);
-	g->m->libcall.n = 2;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2)
-{
-	USED(a0, a1, a2);
-	g->m->libcall.n = 3;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3)
-{
-	USED(a0, a1, a2, a3);
-	g->m->libcall.n = 4;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4)
-{
-	USED(a0, a1, a2, a3, a4);
-	g->m->libcall.n = 5;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5)
-{
-	USED(a0, a1, a2, a3, a4, a5);
-	g->m->libcall.n = 6;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6)
-{
-	USED(a0, a1, a2, a3, a4, a5, a6);
-	g->m->libcall.n = 7;
-	g->m->libcall.args = (uintptr)&a0;
-	return stdcall(fn);
-}
-
-extern void runtime·usleep1(uint32);
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
-	runtime·usleep1(1);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 us)
-{
-	// Have 1us units; want 100ns units.
-	runtime·usleep1(10*us);
-}
-
-uint32
-runtime·issigpanic(uint32 code)
-{
-	switch(code) {
-	case EXCEPTION_ACCESS_VIOLATION:
-	case EXCEPTION_INT_DIVIDE_BY_ZERO:
-	case EXCEPTION_INT_OVERFLOW:
-	case EXCEPTION_FLT_DENORMAL_OPERAND:
-	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
-	case EXCEPTION_FLT_INEXACT_RESULT:
-	case EXCEPTION_FLT_OVERFLOW:
-	case EXCEPTION_FLT_UNDERFLOW:
-	case EXCEPTION_BREAKPOINT:
-		return 1;
-	}
-	return 0;
-}
-
-void
-runtime·initsig(void)
-{
-	// following line keeps these functions alive at link stage
-	// if there's a better way please write it here
-	void *e = runtime·exceptiontramp;
-	void *f = runtime·firstcontinuetramp;
-	void *l = runtime·lastcontinuetramp;
-	USED(e);
-	USED(f);
-	USED(l);
-}
-
-uint32
-runtime·ctrlhandler1(uint32 type)
-{
-	int32 s;
-
-	switch(type) {
-	case CTRL_C_EVENT:
-	case CTRL_BREAK_EVENT:
-		s = SIGINT;
-		break;
-	default:
-		return 0;
-	}
-
-	if(runtime·sigsend(s))
-		return 1;
-	runtime·exit(2);	// SIGINT, SIGTERM, etc
-	return 0;
-}
-
-extern void runtime·dosigprof(Context *r, G *gp, M *mp);
-extern void runtime·profileloop(void);
-#pragma dataflag NOPTR
-static void *profiletimer;
-
-static void
-profilem(M *mp)
-{
-	extern M runtime·m0;
-	extern uint32 runtime·tls0[];
-	byte rbuf[sizeof(Context)+15];
-	Context *r;
-	void *tls;
-	G *gp;
-
-	tls = mp->tls;
-	if(mp == &runtime·m0)
-		tls = runtime·tls0;
-	gp = *(G**)tls;
-
-	// align Context to 16 bytes
-	r = (Context*)((uintptr)(&rbuf[15]) & ~15);
-	r->ContextFlags = CONTEXT_CONTROL;
-	runtime·stdcall2(runtime·GetThreadContext, (uintptr)mp->thread, (uintptr)r);
-	runtime·dosigprof(r, gp, mp);
-}
-
-void
-runtime·profileloop1(void)
-{
-	M *mp, *allm;
-	uintptr thread;
-
-	runtime·stdcall2(runtime·SetThreadPriority, -2, THREAD_PRIORITY_HIGHEST);
-
-	for(;;) {
-		runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)profiletimer, -1);
-		allm = runtime·atomicloadp(&runtime·allm);
-		for(mp = allm; mp != nil; mp = mp->alllink) {
-			thread = runtime·atomicloaduintptr(&mp->thread);
-			// Do not profile threads blocked on Notes,
-			// this includes idle worker threads,
-			// idle timer thread, idle heap scavenger, etc.
-			if(thread == 0 || mp->profilehz == 0 || mp->blocked)
-				continue;
-			runtime·stdcall1(runtime·SuspendThread, (uintptr)thread);
-			if(mp->profilehz != 0 && !mp->blocked)
-				profilem(mp);
-			runtime·stdcall1(runtime·ResumeThread, (uintptr)thread);
-		}
-	}
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	static Mutex lock;
-	void *timer, *thread;
-	int32 ms;
-	int64 due;
-
-	runtime·lock(&lock);
-	if(profiletimer == nil) {
-		timer = runtime·stdcall3(runtime·CreateWaitableTimer, (uintptr)nil, (uintptr)nil, (uintptr)nil);
-		runtime·atomicstorep(&profiletimer, timer);
-		thread = runtime·stdcall6(runtime·CreateThread,
-			(uintptr)nil, (uintptr)nil, (uintptr)runtime·profileloop, (uintptr)nil, (uintptr)nil, (uintptr)nil);
-		runtime·stdcall2(runtime·SetThreadPriority, (uintptr)thread, THREAD_PRIORITY_HIGHEST);
-		runtime·stdcall1(runtime·CloseHandle, (uintptr)thread);
-	}
-	runtime·unlock(&lock);
-
-	ms = 0;
-	due = 1LL<<63;
-	if(hz > 0) {
-		ms = 1000 / hz;
-		if(ms == 0)
-			ms = 1;
-		due = ms * -10000;
-	}
-	runtime·stdcall6(runtime·SetWaitableTimer,
-		(uintptr)profiletimer, (uintptr)&due, ms, (uintptr)nil, (uintptr)nil, (uintptr)nil);
-	runtime·atomicstore((uint32*)&g->m->profilehz, hz);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	return 0;
-}
-
-#pragma dataflag NOPTR
-int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
-int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
-
-void
-runtime·crash(void)
-{
-	// TODO: This routine should do whatever is needed
-	// to make the Windows program abort/crash as it
-	// would if Go was not intercepting signals.
-	// On Unix the routine would remove the custom signal
-	// handler and then raise a signal (like SIGABRT).
-	// Something like that should happen here.
-	// It's okay to leave this empty for now: if crash returns
-	// the ordinary exit-after-panic happens.
-}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index fcd8f44..097b5d6 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -4,24 +4,8 @@
 
 package runtime
 
-import "unsafe"
-
 type stdFunction *byte
 
-func stdcall0(fn stdFunction) uintptr
-func stdcall1(fn stdFunction, a0 uintptr) uintptr
-func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
-func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
-func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
-func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
-func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
-func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
-
-func asmstdcall(fn unsafe.Pointer)
-func getlasterror() uint32
-func setlasterror(err uint32)
-func usleep1(usec uint32)
-
 func os_sigpipe() {
 	gothrow("too many writes on closed pipe")
 }
diff --git a/src/runtime/os_windows.h b/src/runtime/os_windows.h
deleted file mode 100644
index d5d168d..0000000
--- a/src/runtime/os_windows.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2009 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.
-
-extern void *runtime·LoadLibrary;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetQueuedCompletionStatusEx;
-
-// Call a Windows function with stdcall conventions,
-// and switch to os stack during the call.
-void runtime·asmstdcall(void *c);
-void *runtime·stdcall0(void *fn);
-void *runtime·stdcall1(void *fn, uintptr a0);
-void *runtime·stdcall2(void *fn, uintptr a0, uintptr a1);
-void *runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2);
-void *runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3);
-void *runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
-void *runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
-void *runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
-
-uint32 runtime·getlasterror(void);
-void runtime·setlasterror(uint32 err);
-
-// Function to be called by windows CreateThread
-// to start new os thread.
-uint32 runtime·tstart_stdcall(M *newm);
-
-uint32 runtime·issigpanic(uint32);
-void runtime·sigpanic(void);
-uint32 runtime·ctrlhandler(uint32 type);
-
-// Windows dll function to go callback entry.
-byte *runtime·compilecallback(Eface fn, bool cleanstack);
-void *runtime·callbackasm(void);
-
-void runtime·install_exception_handler(void);
-void runtime·remove_exception_handler(void);
-
-// TODO(brainman): should not need those
-enum {
-	NSIG = 65,
-};
diff --git a/src/runtime/os_windows_386.c b/src/runtime/os_windows_386.c
deleted file mode 100644
index 9962f0d..0000000
--- a/src/runtime/os_windows_386.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2009 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·dumpregs(Context *r)
-{
-	runtime·printf("eax     %x\n", r->Eax);
-	runtime·printf("ebx     %x\n", r->Ebx);
-	runtime·printf("ecx     %x\n", r->Ecx);
-	runtime·printf("edx     %x\n", r->Edx);
-	runtime·printf("edi     %x\n", r->Edi);
-	runtime·printf("esi     %x\n", r->Esi);
-	runtime·printf("ebp     %x\n", r->Ebp);
-	runtime·printf("esp     %x\n", r->Esp);
-	runtime·printf("eip     %x\n", r->Eip);
-	runtime·printf("eflags  %x\n", r->EFlags);
-	runtime·printf("cs      %x\n", r->SegCs);
-	runtime·printf("fs      %x\n", r->SegFs);
-	runtime·printf("gs      %x\n", r->SegGs);
-}
-
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
-{
-	extern byte runtime·text[], runtime·etext[];
-
-	// Only handle exception if executing instructions in Go binary
-	// (not Windows library code). 
-	if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip)
-		return false;
-
-	if(!runtime·issigpanic(info->ExceptionCode))
-		return false;
-
-	return true;
-}
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
-// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	uintptr *sp;
-
-	if(!runtime·isgoexception(info, r))
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// Make it look like a call to the signal func.
-	// Have to pass arguments out of band since
-	// augmenting the stack frame would break
-	// the unwinding code.
-	gp->sig = info->ExceptionCode;
-	gp->sigcode0 = info->ExceptionInformation[0];
-	gp->sigcode1 = info->ExceptionInformation[1];
-	gp->sigpc = r->Eip;
-
-	// Only push runtime·sigpanic if r->eip != 0.
-	// If r->eip == 0, probably panicked because of a
-	// call to a nil func.  Not pushing that onto sp will
-	// make the trace look like a call to runtime·sigpanic instead.
-	// (Otherwise the trace will end at runtime·sigpanic and we
-	// won't get to see who faulted.)
-	if(r->Eip != 0) {
-		sp = (uintptr*)r->Esp;
-		*--sp = r->Eip;
-		r->Esp = (uintptr)sp;
-	}
-	r->Eip = (uintptr)runtime·sigpanic;
-	return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	bool crash;
-
-	if(runtime·panicking)	// traceback already printed
-		runtime·exit(2);
-	runtime·panicking = 1;
-
-	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
-		(uintptr)info->ExceptionInformation[0], (uintptr)info->ExceptionInformation[1], (uintptr)r->Eip);
-
-	runtime·printf("PC=%x\n", r->Eip);
-	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = g->m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·tracebacktrap(r->Eip, r->Esp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·dumpregs(r);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-	return 0; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
-	runtime·sigprof((uint8*)r->Eip, (uint8*)r->Esp, nil, gp, mp);
-}
diff --git a/src/runtime/os_windows_amd64.c b/src/runtime/os_windows_amd64.c
deleted file mode 100644
index e4617e4..0000000
--- a/src/runtime/os_windows_amd64.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2011 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·dumpregs(Context *r)
-{
-	runtime·printf("rax     %X\n", r->Rax);
-	runtime·printf("rbx     %X\n", r->Rbx);
-	runtime·printf("rcx     %X\n", r->Rcx);
-	runtime·printf("rdx     %X\n", r->Rdx);
-	runtime·printf("rdi     %X\n", r->Rdi);
-	runtime·printf("rsi     %X\n", r->Rsi);
-	runtime·printf("rbp     %X\n", r->Rbp);
-	runtime·printf("rsp     %X\n", r->Rsp);
-	runtime·printf("r8      %X\n", r->R8 );
-	runtime·printf("r9      %X\n", r->R9 );
-	runtime·printf("r10     %X\n", r->R10);
-	runtime·printf("r11     %X\n", r->R11);
-	runtime·printf("r12     %X\n", r->R12);
-	runtime·printf("r13     %X\n", r->R13);
-	runtime·printf("r14     %X\n", r->R14);
-	runtime·printf("r15     %X\n", r->R15);
-	runtime·printf("rip     %X\n", r->Rip);
-	runtime·printf("rflags  %X\n", r->EFlags);
-	runtime·printf("cs      %X\n", (uint64)r->SegCs);
-	runtime·printf("fs      %X\n", (uint64)r->SegFs);
-	runtime·printf("gs      %X\n", (uint64)r->SegGs);
-}
-
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
-{
-	extern byte runtime·text[], runtime·etext[];
-
-	// Only handle exception if executing instructions in Go binary
-	// (not Windows library code). 
-	if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip)
-		return false;
-
-	if(!runtime·issigpanic(info->ExceptionCode))
-		return false;
-
-	return true;
-}
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
-// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	uintptr *sp;
-
-	if(!runtime·isgoexception(info, r))
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// Make it look like a call to the signal func.
-	// Have to pass arguments out of band since
-	// augmenting the stack frame would break
-	// the unwinding code.
-	gp->sig = info->ExceptionCode;
-	gp->sigcode0 = info->ExceptionInformation[0];
-	gp->sigcode1 = info->ExceptionInformation[1];
-	gp->sigpc = r->Rip;
-
-	// Only push runtime·sigpanic if r->rip != 0.
-	// If r->rip == 0, probably panicked because of a
-	// call to a nil func.  Not pushing that onto sp will
-	// make the trace look like a call to runtime·sigpanic instead.
-	// (Otherwise the trace will end at runtime·sigpanic and we
-	// won't get to see who faulted.)
-	if(r->Rip != 0) {
-		sp = (uintptr*)r->Rsp;
-		*--sp = r->Rip;
-		r->Rsp = (uintptr)sp;
-	}
-	r->Rip = (uintptr)runtime·sigpanic;
-	return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// It seems Windows searches ContinueHandler's list even
-// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
-// firstcontinuehandler will stop that search,
-// if exceptionhandler did the same earlier.
-uint32
-runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	USED(gp);
-	if(!runtime·isgoexception(info, r))
-		return EXCEPTION_CONTINUE_SEARCH;
-	return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	bool crash;
-
-	if(runtime·panicking)	// traceback already printed
-		runtime·exit(2);
-	runtime·panicking = 1;
-
-	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
-		info->ExceptionInformation[0], info->ExceptionInformation[1], r->Rip);
-
-
-	runtime·printf("PC=%X\n", r->Rip);
-	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = g->m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·tracebacktrap(r->Rip, r->Rsp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·dumpregs(r);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-	return 0; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
-	runtime·sigprof((uint8*)r->Rip, (uint8*)r->Rsp, nil, gp, mp);
-}
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
index 526b3c5..cb0b0f0 100644
--- a/src/runtime/stubs2.go
+++ b/src/runtime/stubs2.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build !solaris
+// +build !windows
 
 package runtime
 
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index efbcab5..661ee59d 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -41,20 +41,20 @@
 
 func compileCallback(fn eface, cleanstack bool) (code uintptr) {
 	if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
-		panic("compilecallback: not a function")
+		panic("compileCallback: not a function")
 	}
 	ft := (*functype)(unsafe.Pointer(fn._type))
-	if len(ft.out) != 1 {
-		panic("compilecallback: function must have one output parameter")
+	if ft.out.len != 1 {
+		panic("compileCallback: function must have one output parameter")
 	}
 	uintptrSize := unsafe.Sizeof(uintptr(0))
-	if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
-		panic("compilecallback: output parameter size is wrong")
+	if t := (**_type)(unsafe.Pointer(ft.out.array)); (*t).size != uintptrSize {
+		panic("compileCallback: output parameter size is wrong")
 	}
 	argsize := uintptr(0)
-	for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
+	for _, t := range (*[1024](*_type))(unsafe.Pointer(ft.in.array))[:ft.in.len] {
 		if (*t).size > uintptrSize {
-			panic("compilecallback: input parameter size is wrong")
+			panic("compileCallback: input parameter size is wrong")
 		}
 		argsize += uintptrSize
 	}
@@ -87,8 +87,6 @@
 	return callbackasmAddr(n)
 }
 
-func getLoadLibrary() uintptr
-
 //go:nosplit
 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
 	var c libcall
@@ -103,8 +101,6 @@
 	return
 }
 
-func getGetProcAddress() uintptr
-
 //go:nosplit
 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
 	var c libcall