Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion src/runtime/volatile/register.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
}
6 changes: 6 additions & 0 deletions src/runtime/volatile/volatile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
2 changes: 1 addition & 1 deletion targets/fe310.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"inherits": ["riscv"],
"inherits": ["riscv32"],
"features": ["+a", "+c", "+m"],
"build-tags": ["fe310", "sifive"]
}
2 changes: 1 addition & 1 deletion targets/riscv-qemu.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"inherits": ["riscv"],
"inherits": ["riscv32"],
"features": ["+a", "+c", "+m"],
"build-tags": ["virt", "qemu"],
"linkerscript": "targets/riscv-qemu.ld",
Expand Down
5 changes: 0 additions & 5 deletions targets/riscv.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"llvm-target": "riscv32--none",
"goos": "linux",
"goarch": "arm",
"build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"],
Expand All @@ -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": [
Expand Down
12 changes: 12 additions & 0 deletions targets/riscv32.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"inherits": ["riscv"],
"llvm-target": "riscv32--none",
"cflags": [
"--target=riscv32--none",
"-march=rv32imac",
"-mabi=ilp32"
],
"ldflags": [
"-melf32lriscv"
]
}
13 changes: 13 additions & 0 deletions targets/riscv64.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"inherits": ["riscv"],
"llvm-target": "riscv64--none",
"build-tags": ["tinygo.riscv64"],
"cflags": [
"--target=riscv64--none",
"-march=rv64gc",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming RV64GC is a big assumption but I'm fine with it for now (it can always be changed). The riscv32.json makes a similar assumption.

"-mabi=lp64"
],
"ldflags": [
"-melf64lriscv"
]
}
4 changes: 4 additions & 0 deletions tools/gen-device-svd/gen-device-svd.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,8 @@ var (

var regType string
switch register.elementSize {
case 8:
regType = "volatile.Register64"
case 4:
regType = "volatile.Register32"
case 2:
Expand Down Expand Up @@ -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:
Expand Down