diff options
-rw-r--r-- | compiler/compiler.go | 4 | ||||
-rw-r--r-- | compiler/intrinsics.go | 4 | ||||
-rw-r--r-- | compiler/volatile.go | 25 | ||||
-rw-r--r-- | testdata/atomic.go | 7 | ||||
-rw-r--r-- | testdata/atomic.txt | 1 |
5 files changed, 22 insertions, 19 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go index 191fb5ae9..d54695ff2 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1642,10 +1642,6 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) return b.createSyscall(instr) case strings.HasPrefix(name, "syscall.rawSyscallNoError"): return b.createRawSyscallNoError(instr) - case strings.HasPrefix(name, "runtime/volatile.Load"): - return b.createVolatileLoad(instr) - case strings.HasPrefix(name, "runtime/volatile.Store"): - return b.createVolatileStore(instr) case name == "runtime.supportsRecover": supportsRecover := uint64(0) if b.supportsRecover() { diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go index 50dde981f..00e679e33 100644 --- a/compiler/intrinsics.go +++ b/compiler/intrinsics.go @@ -20,6 +20,10 @@ import ( func (b *builder) defineIntrinsicFunction() { name := b.fn.RelString(nil) switch { + case strings.HasPrefix(name, "runtime/volatile.Load"): + b.createVolatileLoad() + case strings.HasPrefix(name, "runtime/volatile.Store"): + b.createVolatileStore() case strings.HasPrefix(name, "sync/atomic.") && token.IsExported(b.fn.Name()): b.createFunctionStart() returnValue := b.createAtomicOp(b.fn.Name()) diff --git a/compiler/volatile.go b/compiler/volatile.go index 0c9458745..fe690d8b4 100644 --- a/compiler/volatile.go +++ b/compiler/volatile.go @@ -3,28 +3,25 @@ package compiler // This file implements volatile loads/stores in runtime/volatile.LoadT and // runtime/volatile.StoreT as compiler builtins. -import ( - "golang.org/x/tools/go/ssa" - "tinygo.org/x/go-llvm" -) - // createVolatileLoad is the implementation of the intrinsic function // runtime/volatile.LoadT(). -func (b *builder) createVolatileLoad(instr *ssa.CallCommon) (llvm.Value, error) { - addr := b.getValue(instr.Args[0]) - b.createNilCheck(instr.Args[0], addr, "deref") +func (b *builder) createVolatileLoad() { + b.createFunctionStart() + addr := b.getValue(b.fn.Params[0]) + b.createNilCheck(b.fn.Params[0], addr, "deref") val := b.CreateLoad(addr, "") val.SetVolatile(true) - return val, nil + b.CreateRet(val) } // createVolatileStore is the implementation of the intrinsic function // runtime/volatile.StoreT(). -func (b *builder) createVolatileStore(instr *ssa.CallCommon) (llvm.Value, error) { - addr := b.getValue(instr.Args[0]) - val := b.getValue(instr.Args[1]) - b.createNilCheck(instr.Args[0], addr, "deref") +func (b *builder) createVolatileStore() { + b.createFunctionStart() + addr := b.getValue(b.fn.Params[0]) + val := b.getValue(b.fn.Params[1]) + b.createNilCheck(b.fn.Params[0], addr, "deref") store := b.CreateStore(val, addr) store.SetVolatile(true) - return llvm.Value{}, nil + b.CreateRetVoid() } diff --git a/testdata/atomic.go b/testdata/atomic.go index 2b9131c91..4d5ced301 100644 --- a/testdata/atomic.go +++ b/testdata/atomic.go @@ -3,6 +3,8 @@ package main import ( "sync/atomic" "unsafe" + + "runtime/volatile" ) func main() { @@ -82,7 +84,7 @@ func main() { testValue(int(3), int(-2)) testValue("", "foobar", "baz") - // Test atomic operations as deferred values. + // Test atomic and volatile operations as deferred values. testDefer() } @@ -99,8 +101,11 @@ func testValue(values ...interface{}) { func testDefer() { n1 := int32(5) + n2 := uint32(6) defer func() { println("deferred atomic add:", n1) + println("deferred volatile store:", n2) }() defer atomic.AddInt32(&n1, 3) + defer volatile.StoreUint32(&n2, 22) } diff --git a/testdata/atomic.txt b/testdata/atomic.txt index a03f292ce..7bcde9365 100644 --- a/testdata/atomic.txt +++ b/testdata/atomic.txt @@ -34,3 +34,4 @@ StoreUint64: 20 StoreUintptr: 20 StorePointer: true deferred atomic add: 8 +deferred volatile store: 22 |