aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compiler/compiler.go4
-rw-r--r--compiler/intrinsics.go4
-rw-r--r--compiler/volatile.go25
-rw-r--r--testdata/atomic.go7
-rw-r--r--testdata/atomic.txt1
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