mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 04:49:04 +00:00
compiler: really define runtime/volatile.* functions
This makes them available to deferred calls, among others.
This commit is contained in:
committed by
Ron Evans
parent
e1052f921c
commit
1ceb63d14c
@@ -1642,10 +1642,6 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||||||
return b.createSyscall(instr)
|
return b.createSyscall(instr)
|
||||||
case strings.HasPrefix(name, "syscall.rawSyscallNoError"):
|
case strings.HasPrefix(name, "syscall.rawSyscallNoError"):
|
||||||
return b.createRawSyscallNoError(instr)
|
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":
|
case name == "runtime.supportsRecover":
|
||||||
supportsRecover := uint64(0)
|
supportsRecover := uint64(0)
|
||||||
if b.supportsRecover() {
|
if b.supportsRecover() {
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ import (
|
|||||||
func (b *builder) defineIntrinsicFunction() {
|
func (b *builder) defineIntrinsicFunction() {
|
||||||
name := b.fn.RelString(nil)
|
name := b.fn.RelString(nil)
|
||||||
switch {
|
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()):
|
case strings.HasPrefix(name, "sync/atomic.") && token.IsExported(b.fn.Name()):
|
||||||
b.createFunctionStart()
|
b.createFunctionStart()
|
||||||
returnValue := b.createAtomicOp(b.fn.Name())
|
returnValue := b.createAtomicOp(b.fn.Name())
|
||||||
|
|||||||
+11
-14
@@ -3,28 +3,25 @@ package compiler
|
|||||||
// This file implements volatile loads/stores in runtime/volatile.LoadT and
|
// This file implements volatile loads/stores in runtime/volatile.LoadT and
|
||||||
// runtime/volatile.StoreT as compiler builtins.
|
// 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
|
// createVolatileLoad is the implementation of the intrinsic function
|
||||||
// runtime/volatile.LoadT().
|
// runtime/volatile.LoadT().
|
||||||
func (b *builder) createVolatileLoad(instr *ssa.CallCommon) (llvm.Value, error) {
|
func (b *builder) createVolatileLoad() {
|
||||||
addr := b.getValue(instr.Args[0])
|
b.createFunctionStart()
|
||||||
b.createNilCheck(instr.Args[0], addr, "deref")
|
addr := b.getValue(b.fn.Params[0])
|
||||||
|
b.createNilCheck(b.fn.Params[0], addr, "deref")
|
||||||
val := b.CreateLoad(addr, "")
|
val := b.CreateLoad(addr, "")
|
||||||
val.SetVolatile(true)
|
val.SetVolatile(true)
|
||||||
return val, nil
|
b.CreateRet(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createVolatileStore is the implementation of the intrinsic function
|
// createVolatileStore is the implementation of the intrinsic function
|
||||||
// runtime/volatile.StoreT().
|
// runtime/volatile.StoreT().
|
||||||
func (b *builder) createVolatileStore(instr *ssa.CallCommon) (llvm.Value, error) {
|
func (b *builder) createVolatileStore() {
|
||||||
addr := b.getValue(instr.Args[0])
|
b.createFunctionStart()
|
||||||
val := b.getValue(instr.Args[1])
|
addr := b.getValue(b.fn.Params[0])
|
||||||
b.createNilCheck(instr.Args[0], addr, "deref")
|
val := b.getValue(b.fn.Params[1])
|
||||||
|
b.createNilCheck(b.fn.Params[0], addr, "deref")
|
||||||
store := b.CreateStore(val, addr)
|
store := b.CreateStore(val, addr)
|
||||||
store.SetVolatile(true)
|
store.SetVolatile(true)
|
||||||
return llvm.Value{}, nil
|
b.CreateRetVoid()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+6
-1
@@ -3,6 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"runtime/volatile"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -82,7 +84,7 @@ func main() {
|
|||||||
testValue(int(3), int(-2))
|
testValue(int(3), int(-2))
|
||||||
testValue("", "foobar", "baz")
|
testValue("", "foobar", "baz")
|
||||||
|
|
||||||
// Test atomic operations as deferred values.
|
// Test atomic and volatile operations as deferred values.
|
||||||
testDefer()
|
testDefer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +101,11 @@ func testValue(values ...interface{}) {
|
|||||||
|
|
||||||
func testDefer() {
|
func testDefer() {
|
||||||
n1 := int32(5)
|
n1 := int32(5)
|
||||||
|
n2 := uint32(6)
|
||||||
defer func() {
|
defer func() {
|
||||||
println("deferred atomic add:", n1)
|
println("deferred atomic add:", n1)
|
||||||
|
println("deferred volatile store:", n2)
|
||||||
}()
|
}()
|
||||||
defer atomic.AddInt32(&n1, 3)
|
defer atomic.AddInt32(&n1, 3)
|
||||||
|
defer volatile.StoreUint32(&n2, 22)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
@@ -34,3 +34,4 @@ StoreUint64: 20
|
|||||||
StoreUintptr: 20
|
StoreUintptr: 20
|
||||||
StorePointer: true
|
StorePointer: true
|
||||||
deferred atomic add: 8
|
deferred atomic add: 8
|
||||||
|
deferred volatile store: 22
|
||||||
|
|||||||
Reference in New Issue
Block a user