github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/sys_sparc64.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import "unsafe" 8 9 // adjust Gobuf as if it executed a call to fn with context ctxt 10 // and then did an immediate Gosave. 11 func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) { 12 if buf.lr != 0 { 13 throw("invalid use of gostartcall") 14 } 15 buf.lr = buf.pc 16 buf.pc = uintptr(fn) 17 buf.ctxt = ctxt 18 } 19 20 // Called to rewind context saved during morestack back to beginning of function. 21 // To help us, the linker emits a call back to the beginning 8 bytes after the 22 // call to morestack. We just have to decode and apply that jump. 23 func rewindmorestack(buf *gobuf) { 24 var inst uint32 25 if buf.pc&3 == 0 && buf.pc != 0 { 26 // For sparc, the pc register holds the address of the 27 // *current* instruction, rather than the next instruction 28 // to execute, and CTIs are padded with a nop to avoid DCTI 29 // coupling, so we need to skip ahead to get the jump. 30 buf.pc += 8 31 inst = *(*uint32)(unsafe.Pointer(buf.pc)) 32 // Extract opcode 33 op1 := inst >> 30 34 // call and link 35 mop1 := 1 << 30 36 37 call := uint32(mop1 >> 30) 38 if op1 == call { 39 // Extract pc-relative address (4*sign_ext(disp30)) 40 idisp30 := 4 * (int32(inst<<2) >> 2) 41 42 //ipc := uintptr(unsafe.Pointer(buf.pc)) 43 buf.pc += uintptr(idisp30) 44 45 //print("runtime: rewind pc=", hex(ipc), " to pc=", hex(buf.pc), "\n"); 46 return 47 } 48 } 49 print("runtime: pc=", hex(buf.pc), " ", hex(inst), "\n") 50 throw("runtime: misuse of rewindmorestack") 51 } 52 53 func usleep2(us uint32) 54 55 //go:linkname usleep1_go runtime.usleep1 56 //go:nosplit 57 func usleep1_go(µs uint32) { 58 _g_ := getg() 59 60 // Check the validity of m because we might be called in cgo callback 61 // path early enough where there isn't a m available yet. 62 if _g_ != nil && _g_.m != nil { 63 sysvicall1(&libc_usleep, uintptr(µs)) 64 return 65 } 66 usleep2(µs) 67 }