aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/runtime/volatile/register.go64
-rw-r--r--src/runtime/volatile/volatile.go6
-rw-r--r--targets/fe310.json2
-rw-r--r--targets/riscv-qemu.json2
-rw-r--r--targets/riscv.json5
-rw-r--r--targets/riscv32.json12
-rw-r--r--targets/riscv64.json13
-rwxr-xr-xtools/gen-device-svd/gen-device-svd.go4
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: