diff options
Diffstat (limited to 'contrib/bug216610/go/fibber')
-rw-r--r-- | contrib/bug216610/go/fibber/fib.go | 32 | ||||
-rw-r--r-- | contrib/bug216610/go/fibber/fibs_linux_amd64.s | 21 | ||||
-rw-r--r-- | contrib/bug216610/go/fibber/fibs_linux_arm.s | 23 |
3 files changed, 76 insertions, 0 deletions
diff --git a/contrib/bug216610/go/fibber/fib.go b/contrib/bug216610/go/fibber/fib.go new file mode 100644 index 0000000..49757cd --- /dev/null +++ b/contrib/bug216610/go/fibber/fib.go @@ -0,0 +1,32 @@ +// Package fibber implements a Fibonacci sequence generator using a C +// coded compute kernel (a .syso file). +package fibber + +import ( + "unsafe" +) + +// State is the native Go form of the C.state structure. +type State struct { + B, A uint32 +} + +// cPtr converts State into a C pointer suitable as an argument for +// sysoCaller. +func (s *State) cPtr() unsafe.Pointer { + return unsafe.Pointer(&s.B) +} + +// NewState initializes a Fibonacci Number sequence generator. Upon +// return s.A=0 and s.B=1 are the first two numbers in the sequence. +func NewState() *State { + s := &State{} + syso__fib_init.call(s.cPtr()) + return s +} + +// Next advances the state to the next number in the sequence. Upon +// return, s.B is the most recently calculated value. +func (s *State) Next() { + syso__fib_next.call(s.cPtr()) +} diff --git a/contrib/bug216610/go/fibber/fibs_linux_amd64.s b/contrib/bug216610/go/fibber/fibs_linux_amd64.s new file mode 100644 index 0000000..5992d09 --- /dev/null +++ b/contrib/bug216610/go/fibber/fibs_linux_amd64.s @@ -0,0 +1,21 @@ +// To transition from a Go call to a C function call, we are skating +// on really thin ice... Ceveat Emptor! +// +// Ref: +// https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/home +// +// This is not strictly needed, but it makes gdb debugging less +// confusing because spacer ends up being an alias for the TEXT +// section start. +TEXT ·spacer(SB),$0 + RET + +#define RINDEX(n) (8*n) + +// Header to this function wrapper is the last time we can voluntarily +// yield to some other goroutine. +TEXT ·syso(SB),$0-16 + MOVQ cFn+RINDEX(0)(FP), SI + MOVQ state+RINDEX(1)(FP), DI + CALL *SI + RET diff --git a/contrib/bug216610/go/fibber/fibs_linux_arm.s b/contrib/bug216610/go/fibber/fibs_linux_arm.s new file mode 100644 index 0000000..39640a5 --- /dev/null +++ b/contrib/bug216610/go/fibber/fibs_linux_arm.s @@ -0,0 +1,23 @@ +// To transition from a Go call to a C function call, we are skating +// on really thin ice... Ceveat Emptor! +// +// Ref: +// https://stackoverflow.com/questions/261419/what-registers-to-save-in-the-arm-c-calling-convention +// +// This is not strictly needed, but it makes gdb debugging less +// confusing because spacer ends up being an alias for the TEXT +// section start. +TEXT ·spacer(SB),$0 + RET + +#define FINDEX(n) (8*n) + +// Header to this function wrapper is the last time we can voluntarily +// yield to some other goroutine. +// +// Conventions: PC == R15, SP == R13, LR == R14, IP (scratch) = R12 +TEXT ·syso(SB),$0-8 + MOVW cFn+0(FP), R14 + MOVW state+4(FP), R0 + BL (R14) + RET |