Skip to content

Commit 4ddb107

Browse files
committed
riscv: implement 32-bit atomic operations
This is necessary to support the ESP32-C3, which lacks the A (atomic) extension and thus requires these 32-bit atomic operations. With this commit, flashing ./testdata/atomic.go to the ESP32-C3 works correctly and produces the expected output on the serial console.
1 parent 95c2fba commit 4ddb107

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/runtime/arch_tinygoriscv.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,53 @@ func getCurrentStackPointer() uintptr {
1818
// supported RISC-V chips have a single hart, we can simply disable interrupts
1919
// to get the same behavior.
2020

21+
//export __atomic_load_4
22+
func __atomic_load_4(ptr *uint32, ordering int32) uint32 {
23+
mask := riscv.DisableInterrupts()
24+
value := *ptr
25+
riscv.EnableInterrupts(mask)
26+
return value
27+
}
28+
29+
//export __atomic_store_4
30+
func __atomic_store_4(ptr *uint32, value uint32, ordering int32) {
31+
mask := riscv.DisableInterrupts()
32+
*ptr = value
33+
riscv.EnableInterrupts(mask)
34+
}
35+
36+
//export __atomic_exchange_4
37+
func __atomic_exchange_4(ptr *uint32, value uint32, ordering int32) uint32 {
38+
mask := riscv.DisableInterrupts()
39+
oldValue := *ptr
40+
*ptr = value
41+
riscv.EnableInterrupts(mask)
42+
return oldValue
43+
}
44+
45+
//export __atomic_compare_exchange_4
46+
func __atomic_compare_exchange_4(ptr, expected *uint32, desired uint32, success_ordering, failure_ordering int32) bool {
47+
mask := riscv.DisableInterrupts()
48+
oldValue := *ptr
49+
success := oldValue == *expected
50+
if success {
51+
*ptr = desired
52+
} else {
53+
*expected = oldValue
54+
}
55+
riscv.EnableInterrupts(mask)
56+
return success
57+
}
58+
59+
//export __atomic_fetch_add_4
60+
func __atomic_fetch_add_4(ptr *uint32, value uint32, ordering int32) uint32 {
61+
mask := riscv.DisableInterrupts()
62+
oldValue := *ptr
63+
*ptr = oldValue + value
64+
riscv.EnableInterrupts(mask)
65+
return oldValue
66+
}
67+
2168
//export __atomic_load_8
2269
func __atomic_load_8(ptr *uint64, ordering int32) uint64 {
2370
mask := riscv.DisableInterrupts()

0 commit comments

Comments
 (0)