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.
Этот коммит содержится в:
Ayke van Laethem 2021-09-28 00:14:14 +02:00 коммит произвёл Ron Evans
родитель b31d241388
коммит af00e218a8

Просмотреть файл

@ -18,6 +18,53 @@ func getCurrentStackPointer() uintptr {
// supported RISC-V chips have a single hart, we can simply disable interrupts // supported RISC-V chips have a single hart, we can simply disable interrupts
// to get the same behavior. // to get the same behavior.
//export __atomic_load_4
func __atomic_load_4(ptr *uint32, ordering int32) uint32 {
mask := riscv.DisableInterrupts()
value := *ptr
riscv.EnableInterrupts(mask)
return value
}
//export __atomic_store_4
func __atomic_store_4(ptr *uint32, value uint32, ordering int32) {
mask := riscv.DisableInterrupts()
*ptr = value
riscv.EnableInterrupts(mask)
}
//export __atomic_exchange_4
func __atomic_exchange_4(ptr *uint32, value uint32, ordering int32) uint32 {
mask := riscv.DisableInterrupts()
oldValue := *ptr
*ptr = value
riscv.EnableInterrupts(mask)
return oldValue
}
//export __atomic_compare_exchange_4
func __atomic_compare_exchange_4(ptr, expected *uint32, desired uint32, success_ordering, failure_ordering int32) bool {
mask := riscv.DisableInterrupts()
oldValue := *ptr
success := oldValue == *expected
if success {
*ptr = desired
} else {
*expected = oldValue
}
riscv.EnableInterrupts(mask)
return success
}
//export __atomic_fetch_add_4
func __atomic_fetch_add_4(ptr *uint32, value uint32, ordering int32) uint32 {
mask := riscv.DisableInterrupts()
oldValue := *ptr
*ptr = oldValue + value
riscv.EnableInterrupts(mask)
return oldValue
}
//export __atomic_load_8 //export __atomic_load_8
func __atomic_load_8(ptr *uint64, ordering int32) uint64 { func __atomic_load_8(ptr *uint64, ordering int32) uint64 {
mask := riscv.DisableInterrupts() mask := riscv.DisableInterrupts()