diff options
-rw-r--r-- | src/runtime/volatile/register.go | 64 | ||||
-rw-r--r-- | src/runtime/volatile/volatile.go | 6 | ||||
-rw-r--r-- | targets/fe310.json | 2 | ||||
-rw-r--r-- | targets/riscv-qemu.json | 2 | ||||
-rw-r--r-- | targets/riscv.json | 5 | ||||
-rw-r--r-- | targets/riscv32.json | 12 | ||||
-rw-r--r-- | targets/riscv64.json | 13 | ||||
-rwxr-xr-x | tools/gen-device-svd/gen-device-svd.go | 4 |
8 files changed, 100 insertions, 8 deletions
diff --git a/src/runtime/volatile/register.go b/src/runtime/volatile/register.go index 5be97e7fd..adfe372ee 100644 --- a/src/runtime/volatile/register.go +++ b/src/runtime/volatile/register.go @@ -1,6 +1,6 @@ package volatile -// This file defines Register{8,16,32} types, which are convenience types for +// This file defines Register{8,16,32,64} types, which are convenience types for // volatile register accesses. // Special types that causes loads/stores to be volatile (necessary for @@ -190,3 +190,65 @@ func (r *Register32) HasBits(value uint32) bool { func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) { StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos) } + +type Register64 struct { + Reg uint64 +} + +// Get returns the value in the register. It is the volatile equivalent of: +// +// *r.Reg +// +//go:inline +func (r *Register64) Get() uint64 { + return LoadUint64(&r.Reg) +} + +// Set updates the register value. It is the volatile equivalent of: +// +// *r.Reg = value +// +//go:inline +func (r *Register64) Set(value uint64) { + StoreUint64(&r.Reg, value) +} + +// SetBits reads the register, sets the given bits, and writes it back. It is +// the volatile equivalent of: +// +// r.Reg |= value +// +//go:inline +func (r *Register64) SetBits(value uint64) { + StoreUint64(&r.Reg, LoadUint64(&r.Reg)|value) +} + +// ClearBits reads the register, clears the given bits, and writes it back. It +// is the volatile equivalent of: +// +// r.Reg &^= value +// +//go:inline +func (r *Register64) ClearBits(value uint64) { + StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^value) +} + +// HasBits reads the register and then checks to see if the passed bits are set. It +// is the volatile equivalent of: +// +// (*r.Reg & value) > 0 +// +//go:inline +func (r *Register64) HasBits(value uint64) bool { + return (r.Get() & value) > 0 +} + +// ReplaceBits is a helper to simplify setting multiple bits high and/or low at +// once. It is the volatile equivalent of: +// +// r.Reg = (r.Reg & ^(mask << pos)) | value << pos +// +// go:inline +func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) { + StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^(mask<<pos)|value<<pos) +} diff --git a/src/runtime/volatile/volatile.go b/src/runtime/volatile/volatile.go index 47262f347..ce5e69774 100644 --- a/src/runtime/volatile/volatile.go +++ b/src/runtime/volatile/volatile.go @@ -24,6 +24,9 @@ func LoadUint16(addr *uint16) (val uint16) // LoadUint32 loads the volatile value *addr. func LoadUint32(addr *uint32) (val uint32) +// LoadUint64 loads the volatile value *addr. +func LoadUint64(addr *uint64) (val uint64) + // StoreUint8 stores val to the volatile value *addr. func StoreUint8(addr *uint8, val uint8) @@ -32,3 +35,6 @@ func StoreUint16(addr *uint16, val uint16) // StoreUint32 stores val to the volatile value *addr. func StoreUint32(addr *uint32, val uint32) + +// StoreUint64 stores val to the volatile value *addr. +func StoreUint64(addr *uint64, val uint64) diff --git a/targets/fe310.json b/targets/fe310.json index 36bb7452d..76f749705 100644 --- a/targets/fe310.json +++ b/targets/fe310.json @@ -1,5 +1,5 @@ { - "inherits": ["riscv"], + "inherits": ["riscv32"], "features": ["+a", "+c", "+m"], "build-tags": ["fe310", "sifive"] } diff --git a/targets/riscv-qemu.json b/targets/riscv-qemu.json index 9288e4784..4f2c695fe 100644 --- a/targets/riscv-qemu.json +++ b/targets/riscv-qemu.json @@ -1,5 +1,5 @@ { - "inherits": ["riscv"], + "inherits": ["riscv32"], "features": ["+a", "+c", "+m"], "build-tags": ["virt", "qemu"], "linkerscript": "targets/riscv-qemu.ld", diff --git a/targets/riscv.json b/targets/riscv.json index 8874396d1..313aa8581 100644 --- a/targets/riscv.json +++ b/targets/riscv.json @@ -1,5 +1,4 @@ { - "llvm-target": "riscv32--none", "goos": "linux", "goarch": "arm", "build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"], @@ -9,16 +8,12 @@ "rtlib": "compiler-rt", "libc": "picolibc", "cflags": [ - "--target=riscv32--none", - "-march=rv32imac", - "-mabi=ilp32", "-Os", "-Werror", "-fno-exceptions", "-fno-unwind-tables", "-ffunction-sections", "-fdata-sections" ], "ldflags": [ - "-melf32lriscv", "--gc-sections" ], "extra-files": [ diff --git a/targets/riscv32.json b/targets/riscv32.json new file mode 100644 index 000000000..dc07c209c --- /dev/null +++ b/targets/riscv32.json @@ -0,0 +1,12 @@ +{ + "inherits": ["riscv"], + "llvm-target": "riscv32--none", + "cflags": [ + "--target=riscv32--none", + "-march=rv32imac", + "-mabi=ilp32" + ], + "ldflags": [ + "-melf32lriscv" + ] +} diff --git a/targets/riscv64.json b/targets/riscv64.json new file mode 100644 index 000000000..a2a0641f9 --- /dev/null +++ b/targets/riscv64.json @@ -0,0 +1,13 @@ +{ + "inherits": ["riscv"], + "llvm-target": "riscv64--none", + "build-tags": ["tinygo.riscv64"], + "cflags": [ + "--target=riscv64--none", + "-march=rv64gc", + "-mabi=lp64" + ], + "ldflags": [ + "-melf64lriscv" + ] +} diff --git a/tools/gen-device-svd/gen-device-svd.go b/tools/gen-device-svd/gen-device-svd.go index 2e64651e5..c32cf9734 100755 --- a/tools/gen-device-svd/gen-device-svd.go +++ b/tools/gen-device-svd/gen-device-svd.go @@ -681,6 +681,8 @@ var ( var regType string switch register.elementSize { + case 8: + regType = "volatile.Register64" case 4: regType = "volatile.Register32" case 2: @@ -710,6 +712,8 @@ var ( for _, subregister := range register.registers { var subregType string switch subregister.elementSize { + case 8: + subregType = "volatile.Register64" case 4: subregType = "volatile.Register32" case 2: |